From 5ffa52cab5556639a327471e1927787af6a18231 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Minh=20Nguy=E1=BB=85n?= Date: Mon, 27 Apr 2015 15:52:30 -0700 Subject: [PATCH] Automatically find view controller for layout guides Find the managing view controller by traversing the responder chain. --- include/mbgl/ios/MGLMapView.h | 5 ----- ios/app/MBXViewController.mm | 1 - platform/ios/MGLMapView.mm | 42 +++++++++++++++++++---------------- test/ios/MGLTViewController.m | 1 - 4 files changed, 23 insertions(+), 26 deletions(-) diff --git a/include/mbgl/ios/MGLMapView.h b/include/mbgl/ios/MGLMapView.h index 8717b5e8a..88d75088b 100644 --- a/include/mbgl/ios/MGLMapView.h +++ b/include/mbgl/ios/MGLMapView.h @@ -46,11 +46,6 @@ IB_DESIGNABLE /** @name Managing Constraints */ -/** A view controller whose top and bottom layout guides to use for proper setup of constraints in the map view internals. -* -* Certain components of the map view, such as the heading compass and the data attribution button, need to be aware of the view controller layout in order to avoid positioning content under a top navigation bar or a bottom toolbar. */ -@property (nonatomic, weak) IBOutlet UIViewController *viewControllerForLayoutGuides; - #pragma mark - Accessing Map Properties /** @name Accessing Map Properties */ diff --git a/ios/app/MBXViewController.mm b/ios/app/MBXViewController.mm index 13235beb0..98c8e016d 100644 --- a/ios/app/MBXViewController.mm +++ b/ios/app/MBXViewController.mm @@ -67,7 +67,6 @@ mbgl::Settings_NSUserDefaults *settings = nullptr; self.mapView = [[MGLMapView alloc] initWithFrame:self.view.bounds accessToken:accessToken]; self.mapView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; - self.mapView.viewControllerForLayoutGuides = self; self.mapView.showsUserLocation = YES; self.mapView.delegate = self; [self.view addSubview:self.mapView]; diff --git a/platform/ios/MGLMapView.mm b/platform/ios/MGLMapView.mm index b61679a7d..d90f99e0e 100644 --- a/platform/ios/MGLMapView.mm +++ b/platform/ios/MGLMapView.mm @@ -323,8 +323,6 @@ mbgl::DefaultFileSource *mbglFileSource = nullptr; [container addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleCompassTapGesture:)]]; [self addSubview:container]; - self.viewControllerForLayoutGuides = nil; - // setup interaction // _pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handlePanGesture:)]; @@ -476,15 +474,22 @@ mbgl::DefaultFileSource *mbglFileSource = nullptr; [self setNeedsUpdateConstraints]; } -- (void)setViewControllerForLayoutGuides:(UIViewController *)viewController +- (UIViewController *)viewControllerForLayoutGuides { - _viewControllerForLayoutGuides = viewController; - - [self.compass.superview removeConstraints:self.compass.superview.constraints]; - [self.logoBug removeConstraints:self.logoBug.constraints]; - [self.attributionButton removeConstraints:self.attributionButton.constraints]; - - [self setNeedsUpdateConstraints]; + // Per -[UIResponder nextResponder] documentation, a UIView’s next responder + // is its managing UIViewController if applicable, or otherwise its + // superview. UIWindow’s next responder is UIApplication, which has no next + // responder. + UIResponder *laterResponder = self; + while ([laterResponder isKindOfClass:[UIView class]]) + { + laterResponder = laterResponder.nextResponder; + } + if ([laterResponder isKindOfClass:[UIViewController class]]) + { + return (UIViewController *)laterResponder; + } + return nil; } - (void)updateConstraints @@ -493,21 +498,20 @@ mbgl::DefaultFileSource *mbglFileSource = nullptr; // views so they don't underlap navigation or tool bars. If we don't have a reference, apply // constraints against ourself to maintain (albeit less ideal) placement of the subviews. // - UIView *constraintParentView = (self.viewControllerForLayoutGuides.view ? - self.viewControllerForLayoutGuides.view : - self); + UIViewController *viewController = self.viewControllerForLayoutGuides; + UIView *constraintParentView = (viewController.view ? viewController.view : self); // compass // UIView *compassContainer = self.compass.superview; - if (self.viewControllerForLayoutGuides) + if (viewController) { [constraintParentView addConstraint: [NSLayoutConstraint constraintWithItem:compassContainer attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationGreaterThanOrEqual - toItem:self.viewControllerForLayoutGuides.topLayoutGuide + toItem:viewController.topLayoutGuide attribute:NSLayoutAttributeBottom multiplier:1 constant:5]]; @@ -550,10 +554,10 @@ mbgl::DefaultFileSource *mbglFileSource = nullptr; // logo bug // - if (self.viewControllerForLayoutGuides) + if (viewController) { [constraintParentView addConstraint: - [NSLayoutConstraint constraintWithItem:self.viewControllerForLayoutGuides.bottomLayoutGuide + [NSLayoutConstraint constraintWithItem:viewController.bottomLayoutGuide attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationGreaterThanOrEqual toItem:self.logoBug @@ -581,10 +585,10 @@ mbgl::DefaultFileSource *mbglFileSource = nullptr; // attribution button // - if (self.viewControllerForLayoutGuides) + if (viewController) { [constraintParentView addConstraint: - [NSLayoutConstraint constraintWithItem:self.viewControllerForLayoutGuides.bottomLayoutGuide + [NSLayoutConstraint constraintWithItem:viewController.bottomLayoutGuide attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationGreaterThanOrEqual toItem:self.attributionButton diff --git a/test/ios/MGLTViewController.m b/test/ios/MGLTViewController.m index e8b500b43..bdce2202d 100644 --- a/test/ios/MGLTViewController.m +++ b/test/ios/MGLTViewController.m @@ -12,7 +12,6 @@ _mapView = [[MGLMapView alloc] initWithFrame:self.view.bounds accessToken:@"pk.eyJ1IjoianVzdGluIiwiYSI6Ik9RX3RRQzAifQ.dmOg_BAp1ywuDZMM7YsXRg"]; - _mapView.viewControllerForLayoutGuides = self; _mapView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; [self.view addSubview:_mapView];