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.

140 lines
5.1 KiB

2 years ago
#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