summaryrefslogtreecommitdiff
path: root/platform/ios/src/MGLMapView.mm
diff options
context:
space:
mode:
Diffstat (limited to 'platform/ios/src/MGLMapView.mm')
-rw-r--r--platform/ios/src/MGLMapView.mm98
1 files changed, 61 insertions, 37 deletions
diff --git a/platform/ios/src/MGLMapView.mm b/platform/ios/src/MGLMapView.mm
index 62b943fd3d..6f0257a0d8 100644
--- a/platform/ios/src/MGLMapView.mm
+++ b/platform/ios/src/MGLMapView.mm
@@ -274,6 +274,10 @@ public:
/// Tilt gesture recognizer helper
@property (nonatomic, assign) CGPoint dragGestureMiddlePoint;
+/// This property is used to keep track of the view's safe edge insets
+/// and calculate the ornament's position
+@property (nonatomic, assign) UIEdgeInsets safeMapViewContentInsets;
+
- (mbgl::Map &)mbglMap;
@end
@@ -518,6 +522,8 @@ public:
_annotationViewReuseQueueByIdentifier = [NSMutableDictionary dictionary];
_selectedAnnotationTag = MGLAnnotationTagNotFound;
_annotationsNearbyLastTap = {};
+
+ _automaticallyAdjustContentInset = YES;
// setup logo
//
@@ -832,23 +838,31 @@ public:
size:(CGSize)size
margins:(CGPoint)margins {
NSMutableArray *updatedConstraints = [NSMutableArray array];
+ UIEdgeInsets inset = UIEdgeInsetsZero;
+
+ if (! self.automaticallyAdjustContentInset) {
+ inset = UIEdgeInsetsMake(self.contentInset.top - self.safeMapViewContentInsets.top,
+ self.contentInset.left - self.safeMapViewContentInsets.left,
+ self.contentInset.bottom - self.safeMapViewContentInsets.bottom,
+ self.contentInset.right - self.safeMapViewContentInsets.right);
+ }
switch (position) {
case MGLOrnamentPositionTopLeft:
- [updatedConstraints addObject:[view.topAnchor constraintEqualToAnchor:self.mgl_safeTopAnchor constant:margins.y]];
- [updatedConstraints addObject:[view.leadingAnchor constraintEqualToAnchor:self.mgl_safeLeadingAnchor constant:margins.x]];
+ [updatedConstraints addObject:[view.topAnchor constraintEqualToAnchor:self.mgl_safeTopAnchor constant:margins.y + inset.top]];
+ [updatedConstraints addObject:[view.leadingAnchor constraintEqualToAnchor:self.mgl_safeLeadingAnchor constant:margins.x + inset.left]];
break;
case MGLOrnamentPositionTopRight:
- [updatedConstraints addObject:[view.topAnchor constraintEqualToAnchor:self.mgl_safeTopAnchor constant:margins.y]];
- [updatedConstraints addObject:[self.mgl_safeTrailingAnchor constraintEqualToAnchor:view.trailingAnchor constant:margins.x]];
+ [updatedConstraints addObject:[view.topAnchor constraintEqualToAnchor:self.mgl_safeTopAnchor constant:margins.y + inset.top]];
+ [updatedConstraints addObject:[self.mgl_safeTrailingAnchor constraintEqualToAnchor:view.trailingAnchor constant:margins.x + inset.right]];
break;
case MGLOrnamentPositionBottomLeft:
- [updatedConstraints addObject:[self.mgl_safeBottomAnchor constraintEqualToAnchor:view.bottomAnchor constant:margins.y]];
- [updatedConstraints addObject:[view.leadingAnchor constraintEqualToAnchor:self.mgl_safeLeadingAnchor constant:margins.x]];
+ [updatedConstraints addObject:[self.mgl_safeBottomAnchor constraintEqualToAnchor:view.bottomAnchor constant:margins.y + inset.bottom]];
+ [updatedConstraints addObject:[view.leadingAnchor constraintEqualToAnchor:self.mgl_safeLeadingAnchor constant:margins.x + inset.left]];
break;
case MGLOrnamentPositionBottomRight:
- [updatedConstraints addObject:[self.mgl_safeBottomAnchor constraintEqualToAnchor:view.bottomAnchor constant:margins.y]];
- [updatedConstraints addObject: [self.mgl_safeTrailingAnchor constraintEqualToAnchor:view.trailingAnchor constant:margins.x]];
+ [updatedConstraints addObject:[self.mgl_safeBottomAnchor constraintEqualToAnchor:view.bottomAnchor constant:margins.y + inset.bottom]];
+ [updatedConstraints addObject: [self.mgl_safeTrailingAnchor constraintEqualToAnchor:view.trailingAnchor constant:margins.x + inset.right]];
break;
}
@@ -967,40 +981,44 @@ public:
/// Updates `contentInset` to reflect the current window geometry.
- (void)adjustContentInset
{
- // We could crawl all the way up the responder chain using
- // -viewControllerForLayoutGuides, but an intervening view means that any
- // manual contentInset should not be overridden; something other than the
- // top and bottom bars may be influencing the manual inset.
- UIViewController *viewController;
- if ([self.nextResponder isKindOfClass:[UIViewController class]])
- {
- // This map view is the content view of a view controller.
- viewController = (UIViewController *)self.nextResponder;
- }
- else if ([self.superview.nextResponder isKindOfClass:[UIViewController class]])
+ UIEdgeInsets adjustedContentInsets = UIEdgeInsetsZero;
+
+ if (@available(iOS 11.0, *))
{
- // This map view is an immediate child of a view controller’s content view.
- viewController = (UIViewController *)self.superview.nextResponder;
- }
+ adjustedContentInsets = self.safeAreaInsets;
+
+ } else {
+ // We could crawl all the way up the responder chain using
+ // -viewControllerForLayoutGuides, but an intervening view means that any
+ // manual contentInset should not be overridden; something other than the
+ // top and bottom bars may be influencing the manual inset.
+ UIViewController *viewController;
+ if ([self.nextResponder isKindOfClass:[UIViewController class]])
+ {
+ // This map view is the content view of a view controller.
+ viewController = (UIViewController *)self.nextResponder;
+ }
+ else if ([self.superview.nextResponder isKindOfClass:[UIViewController class]])
+ {
+ // This map view is an immediate child of a view controller’s content view.
+ viewController = (UIViewController *)self.superview.nextResponder;
+ }
+
+ adjustedContentInsets.top = viewController.topLayoutGuide.length;
+ CGFloat bottomPoint = CGRectGetMaxY(viewController.view.bounds) -
+ (CGRectGetMaxY(viewController.view.bounds)
+ - viewController.bottomLayoutGuide.length);
+ adjustedContentInsets.bottom = bottomPoint;
- if ( ! viewController.automaticallyAdjustsScrollViewInsets)
+ }
+
+ self.safeMapViewContentInsets = adjustedContentInsets;
+ if ( ! self.automaticallyAdjustContentInset)
{
return;
}
-
- UIEdgeInsets contentInset = UIEdgeInsetsZero;
- CGPoint topPoint = CGPointMake(0, viewController.topLayoutGuide.length);
- contentInset.top = [self convertPoint:topPoint fromView:viewController.view].y;
- CGPoint bottomPoint = CGPointMake(0, CGRectGetMaxY(viewController.view.bounds)
- - viewController.bottomLayoutGuide.length);
- contentInset.bottom = (CGRectGetMaxY(self.bounds)
- - [self convertPoint:bottomPoint fromView:viewController.view].y);
-
- // Negative insets are invalid, replace with 0.
- contentInset.top = fmaxf(contentInset.top, 0);
- contentInset.bottom = fmaxf(contentInset.bottom, 0);
-
- self.contentInset = contentInset;
+
+ self.contentInset = adjustedContentInsets;
}
- (void)setContentInset:(UIEdgeInsets)contentInset
@@ -1015,6 +1033,12 @@ public:
- (void)setContentInset:(UIEdgeInsets)contentInset animated:(BOOL)animated completionHandler:(nullable void (^)(void))completion
{
+ // makes sure the insets don't have negative values that could hide the ornaments
+ // thus violating our ToS
+ contentInset = UIEdgeInsetsMake(fmaxf(contentInset.top, 0),
+ fmaxf(contentInset.left, 0),
+ fmaxf(contentInset.bottom, 0),
+ fmaxf(contentInset.right, 0));
MGLLogDebug(@"Setting contentInset: %@ animated:", NSStringFromUIEdgeInsets(contentInset), MGLStringFromBOOL(animated));
if (UIEdgeInsetsEqualToEdgeInsets(contentInset, self.contentInset))
{