You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
139 lines
5.1 KiB
139 lines
5.1 KiB
#if !defined(__has_feature) || !__has_feature(objc_arc) |
|
#error "This file requires ARC support." |
|
#endif |
|
|
|
#import "GoogleMapsDemos/Samples/CustomIndoorViewController.h" |
|
|
|
#import <GoogleMaps/GoogleMaps.h> |
|
|
|
@interface CustomIndoorViewController () < |
|
GMSIndoorDisplayDelegate, |
|
UIPickerViewDelegate, |
|
UIPickerViewDataSource> |
|
|
|
@end |
|
|
|
@implementation CustomIndoorViewController { |
|
GMSMapView *_mapView; |
|
UIPickerView *_levelPickerView; |
|
NSArray *_levels; |
|
} |
|
|
|
- (void)viewDidLoad { |
|
[super viewDidLoad]; |
|
GMSCameraPosition *camera = [GMSCameraPosition cameraWithLatitude:37.78318 |
|
longitude:-122.403874 |
|
zoom:18]; |
|
|
|
// set backgroundColor, otherwise UIPickerView fades into the background |
|
self.view.backgroundColor = [UIColor grayColor]; |
|
|
|
_mapView = [GMSMapView mapWithFrame:CGRectZero camera:camera]; |
|
_mapView.settings.myLocationButton = NO; |
|
_mapView.settings.indoorPicker = NO; // We are implementing a custom level picker. |
|
|
|
_mapView.indoorEnabled = YES; // Defaults to YES. Set to NO to hide indoor maps. |
|
_mapView.indoorDisplay.delegate = self; |
|
_mapView.translatesAutoresizingMaskIntoConstraints = NO; |
|
[self.view addSubview:_mapView]; |
|
|
|
// This UIPickerView will be populated with the levels of the active building. |
|
_levelPickerView = [[UIPickerView alloc] init]; |
|
_levelPickerView.delegate = self; |
|
_levelPickerView.dataSource = self; |
|
_levelPickerView.showsSelectionIndicator = YES; |
|
_levelPickerView.translatesAutoresizingMaskIntoConstraints = NO; |
|
[self.view addSubview:_levelPickerView]; |
|
|
|
// The height of the UIPickerView, used below in the vertical constraint |
|
NSDictionary *metrics = @{@"height": @180.0}; |
|
NSDictionary *views = NSDictionaryOfVariableBindings(_mapView, _levelPickerView); |
|
|
|
// Constraining the map to the full width of the display. |
|
// The |_levelPickerView| is constrained below with the NSLayoutFormatAlignAll* |
|
// See http://developer.apple.com/library/ios/documentation/UserExperience/Conceptual/AutolayoutPG/Articles/formatLanguage.html |
|
[self.view addConstraints:[NSLayoutConstraint |
|
constraintsWithVisualFormat:@"|[_mapView]|" |
|
options:0 |
|
metrics:metrics |
|
views:views]]; |
|
|
|
// Constraining the _mapView and the _levelPickerView as siblings taking |
|
// the full height of the display, with _levelPickerView at 200 points high |
|
[self.view addConstraints:[NSLayoutConstraint |
|
constraintsWithVisualFormat:@"V:|[_mapView][_levelPickerView(height)]|" |
|
options:NSLayoutFormatAlignAllLeft|NSLayoutFormatAlignAllRight |
|
metrics:metrics |
|
views:views]]; |
|
} |
|
|
|
#pragma mark - GMSIndoorDisplayDelegate |
|
|
|
- (void)didChangeActiveBuilding:(GMSIndoorBuilding *)building { |
|
// Everytime we change active building force the picker to re-display the labels. |
|
|
|
NSMutableArray *levels = [NSMutableArray array]; |
|
if (building.underground) { |
|
// If this building is completely underground, add a fake 'top' floor. This must be the 'boxed' |
|
// nil, [NSNull null], as NSArray/NSMutableArray cannot contain nils. |
|
[levels addObject:[NSNull null]]; |
|
} |
|
[levels addObjectsFromArray:building.levels]; |
|
_levels = [levels copy]; |
|
|
|
[_levelPickerView reloadAllComponents]; |
|
[_levelPickerView selectRow:-1 inComponent:0 animated:NO]; |
|
|
|
// UIPickerView insists on having some data; disable interaction if there's no levels. |
|
_levelPickerView.userInteractionEnabled = ([_levels count] > 0); |
|
} |
|
|
|
- (void)didChangeActiveLevel:(GMSIndoorLevel *)level { |
|
// On level change, sync our level picker's selection to the IndoorDisplay. |
|
if (level == nil) { |
|
level = (id)[NSNull null]; // box nil to NSNull for use in NSArray |
|
} |
|
NSUInteger index = [_levels indexOfObject:level]; |
|
if (index != NSNotFound) { |
|
NSInteger currentlySelectedLevel = [_levelPickerView selectedRowInComponent:0]; |
|
if ((NSInteger)index != currentlySelectedLevel) { |
|
[_levelPickerView selectRow:index inComponent:0 animated:NO]; |
|
} |
|
} |
|
} |
|
|
|
#pragma mark - UIPickerViewDelegate |
|
|
|
- (void)pickerView:(UIPickerView *)pickerView |
|
didSelectRow:(NSInteger)row |
|
inComponent:(NSInteger)component { |
|
// On user selection of a level in the picker, set the right level in IndoorDisplay |
|
id level = _levels[row]; |
|
if (level == [NSNull null]) { |
|
level = nil; // unbox NSNull |
|
} |
|
[_mapView.indoorDisplay setActiveLevel:level]; |
|
} |
|
|
|
- (NSString *)pickerView:(UIPickerView *)pickerView |
|
titleForRow:(NSInteger)row |
|
forComponent:(NSInteger)component { |
|
id object = _levels[row]; |
|
if (object == [NSNull null]) { |
|
return @"\u2014"; // use an em dash for 'above ground' |
|
} |
|
GMSIndoorLevel *level = object; |
|
return level.name; |
|
} |
|
|
|
#pragma mark - UIPickerViewDataSource |
|
|
|
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView { |
|
return 1; |
|
} |
|
|
|
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component { |
|
return [_levels count]; |
|
} |
|
|
|
@end
|
|
|