CustomIndoorViewController.m 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. /*
  2. * Copyright 2016 Google Inc. All rights reserved.
  3. *
  4. *
  5. * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this
  6. * file except in compliance with the License. You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software distributed under
  11. * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
  12. * ANY KIND, either express or implied. See the License for the specific language governing
  13. * permissions and limitations under the License.
  14. */
  15. #import "GoogleMapsDemos/Samples/CustomIndoorViewController.h"
  16. #import <GoogleMaps/GoogleMaps.h>
  17. @interface CustomIndoorViewController () <
  18. GMSIndoorDisplayDelegate,
  19. UIPickerViewDelegate,
  20. UIPickerViewDataSource>
  21. @end
  22. @implementation CustomIndoorViewController {
  23. GMSMapView *_mapView;
  24. UIPickerView *_levelPickerView;
  25. NSArray *_levels;
  26. }
  27. - (void)viewDidLoad {
  28. [super viewDidLoad];
  29. GMSCameraPosition *camera = [GMSCameraPosition cameraWithLatitude:37.78318
  30. longitude:-122.403874
  31. zoom:18];
  32. // set backgroundColor, otherwise UIPickerView fades into the background
  33. self.view.backgroundColor = [UIColor grayColor];
  34. _mapView = [GMSMapView mapWithFrame:CGRectZero camera:camera];
  35. _mapView.settings.myLocationButton = NO;
  36. _mapView.settings.indoorPicker = NO; // We are implementing a custom level picker.
  37. _mapView.indoorEnabled = YES; // Defaults to YES. Set to NO to hide indoor maps.
  38. _mapView.indoorDisplay.delegate = self;
  39. _mapView.translatesAutoresizingMaskIntoConstraints = NO;
  40. [self.view addSubview:_mapView];
  41. // This UIPickerView will be populated with the levels of the active building.
  42. _levelPickerView = [[UIPickerView alloc] init];
  43. _levelPickerView.delegate = self;
  44. _levelPickerView.dataSource = self;
  45. _levelPickerView.showsSelectionIndicator = YES;
  46. _levelPickerView.translatesAutoresizingMaskIntoConstraints = NO;
  47. [self.view addSubview:_levelPickerView];
  48. // The height of the UIPickerView, used below in the vertical constraint
  49. NSDictionary *metrics = @{@"height": @180.0};
  50. NSDictionary *views = NSDictionaryOfVariableBindings(_mapView, _levelPickerView);
  51. // Constraining the map to the full width of the display.
  52. // The |_levelPickerView| is constrained below with the NSLayoutFormatAlignAll*
  53. // See http://developer.apple.com/library/ios/documentation/UserExperience/Conceptual/AutolayoutPG/Articles/formatLanguage.html
  54. [self.view addConstraints:[NSLayoutConstraint
  55. constraintsWithVisualFormat:@"|[_mapView]|"
  56. options:0
  57. metrics:metrics
  58. views:views]];
  59. // Constraining the _mapView and the _levelPickerView as siblings taking
  60. // the full height of the display, with _levelPickerView at 200 points high
  61. [self.view addConstraints:[NSLayoutConstraint
  62. constraintsWithVisualFormat:@"V:|[_mapView][_levelPickerView(height)]|"
  63. options:NSLayoutFormatAlignAllLeft|NSLayoutFormatAlignAllRight
  64. metrics:metrics
  65. views:views]];
  66. }
  67. #pragma mark - GMSIndoorDisplayDelegate
  68. - (void)didChangeActiveBuilding:(GMSIndoorBuilding *)building {
  69. // Everytime we change active building force the picker to re-display the labels.
  70. NSMutableArray *levels = [NSMutableArray array];
  71. if (building.underground) {
  72. // If this building is completely underground, add a fake 'top' floor. This must be the 'boxed'
  73. // nil, [NSNull null], as NSArray/NSMutableArray cannot contain nils.
  74. [levels addObject:[NSNull null]];
  75. }
  76. [levels addObjectsFromArray:building.levels];
  77. _levels = [levels copy];
  78. [_levelPickerView reloadAllComponents];
  79. [_levelPickerView selectRow:-1 inComponent:0 animated:NO];
  80. // UIPickerView insists on having some data; disable interaction if there's no levels.
  81. _levelPickerView.userInteractionEnabled = (_levels.count > 0);
  82. }
  83. - (void)didChangeActiveLevel:(GMSIndoorLevel *)level {
  84. // On level change, sync our level picker's selection to the IndoorDisplay.
  85. if (level == nil) {
  86. level = (id)[NSNull null]; // box nil to NSNull for use in NSArray
  87. }
  88. NSUInteger index = [_levels indexOfObject:level];
  89. if (index != NSNotFound) {
  90. NSInteger currentlySelectedLevel = [_levelPickerView selectedRowInComponent:0];
  91. if ((NSInteger)index != currentlySelectedLevel) {
  92. [_levelPickerView selectRow:index inComponent:0 animated:NO];
  93. }
  94. }
  95. }
  96. #pragma mark - UIPickerViewDelegate
  97. - (void)pickerView:(UIPickerView *)pickerView
  98. didSelectRow:(NSInteger)row
  99. inComponent:(NSInteger)component {
  100. // On user selection of a level in the picker, set the right level in IndoorDisplay
  101. id level = _levels[row];
  102. if (level == [NSNull null]) {
  103. level = nil; // unbox NSNull
  104. }
  105. [_mapView.indoorDisplay setActiveLevel:level];
  106. }
  107. - (NSString *)pickerView:(UIPickerView *)pickerView
  108. titleForRow:(NSInteger)row
  109. forComponent:(NSInteger)component {
  110. id object = _levels[row];
  111. if (object == [NSNull null]) {
  112. return @"\u2014"; // use an em dash for 'above ground'
  113. }
  114. GMSIndoorLevel *level = object;
  115. return level.name;
  116. }
  117. #pragma mark - UIPickerViewDataSource
  118. - (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView {
  119. return 1;
  120. }
  121. - (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component {
  122. return _levels.count;
  123. }
  124. @end