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
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
|