summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFabian Guerra <fabian.guerra@mapbox.com>2019-09-09 15:30:10 -0700
committerFabian Guerra <fabian.guerra@mapbox.com>2019-10-03 10:27:10 -0700
commit02940317aae4c8aa54e624256153c7a5a645c7b3 (patch)
treeefb8e20e4464aade577d006ea0ae626c398ab0c0
parentae5ed02b72c813877d21cce6bd6e1738f0edcf84 (diff)
downloadqtlocation-mapboxgl-02940317aae4c8aa54e624256153c7a5a645c7b3.tar.gz
[ios] Fix automaticallyAdjustsScrollViewInsets legacy behavior.
The property automaticallyAdjustsScrollViewInsets overrode automaticallyAdjustsScrollViewInsets which caused a breaking change. This is fixed to consider the legacy property when calculating the content insets and added tests for both cases.
-rw-r--r--platform/ios/src/MGLMapView.h31
-rw-r--r--platform/ios/src/MGLMapView.mm84
-rw-r--r--platform/ios/test/MGLMapViewContentInsetTests.m30
3 files changed, 106 insertions, 39 deletions
diff --git a/platform/ios/src/MGLMapView.h b/platform/ios/src/MGLMapView.h
index 1ad7e8f594..1b6c989d94 100644
--- a/platform/ios/src/MGLMapView.h
+++ b/platform/ios/src/MGLMapView.h
@@ -294,8 +294,6 @@ MGL_EXPORT
`contentInset` property to account for any area not covered by navigation bars,
tab bars, toolbars, and other ancestors that obscure the map view.
- The default value of this property is `YES`.
-
*/
@property (assign) BOOL automaticallyAdjustContentInset;
@@ -1321,10 +1319,13 @@ MGL_EXPORT
view’s frame. Otherwise, those properties are inset, excluding part of the
frame from the viewport. For instance, if the only the top edge is inset, the
map center is effectively shifted downward.
-
- When the map view’s property `automaticallyAdjustContentInset` is set to `YES`,
- the value of this property may be overridden at any time. To persist the value
- set it to `NO`.
+
+ When the map view’s superview is an instance of `UIViewController` whose
+ `automaticallyAdjustsScrollViewInsets` property is `YES`, the value of this
+ property may be overridden at any time.
+
+ The usage of `automaticallyAdjustsScrollViewInsets` it is been deprecated
+ use the map view’s property `automaticallyAdjustContentInset`instead.
Changing the value of this property updates the map view immediately. If you
want to animate the change, use the `-setContentInset:animated:completionHandler:`
@@ -1342,9 +1343,12 @@ MGL_EXPORT
frame from the viewport. For instance, if the only the top edge is inset, the
map center is effectively shifted downward.
- When the map view’s property `automaticallyAdjustContentInset` is set to `YES`,
- the value of this property may be overridden at any time. To persist the value
- set it to `NO`.
+ When the map view’s superview is an instance of `UIViewController` whose
+ `automaticallyAdjustsScrollViewInsets` property is `YES`, the value of this
+ property may be overridden at any time.
+
+ The usage of `automaticallyAdjustsScrollViewInsets` it is been deprecated
+ use the map view’s property `automaticallyAdjustContentInset`instead.
To specify a completion handler to execute after the animation finishes, use
the `-setContentInset:animated:completionHandler:` method.
@@ -1367,9 +1371,12 @@ MGL_EXPORT
frame from the viewport. For instance, if the only the top edge is inset, the
map center is effectively shifted downward.
- When the map view’s property `automaticallyAdjustContentInset` is set to `YES`,
- the value of this property may be overridden at any time. To persist the value
- set it to `NO`.
+ When the map view’s superview is an instance of `UIViewController` whose
+ `automaticallyAdjustsScrollViewInsets` property is `YES`, the value of this
+ property may be overridden at any time.
+
+ The usage of `automaticallyAdjustsScrollViewInsets` it is been deprecated
+ use the map view’s property `automaticallyAdjustContentInset`instead.
@param contentInset The new values to inset the content by.
@param animated Specify `YES` if you want the map view to animate the change to
diff --git a/platform/ios/src/MGLMapView.mm b/platform/ios/src/MGLMapView.mm
index 6f0257a0d8..27ffe5fba5 100644
--- a/platform/ios/src/MGLMapView.mm
+++ b/platform/ios/src/MGLMapView.mm
@@ -277,6 +277,7 @@ public:
/// 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;
+@property (nonatomic, strong) NSNumber *automaticallyAdjustContentInsetHolder;
- (mbgl::Map &)mbglMap;
@@ -523,7 +524,10 @@ public:
_selectedAnnotationTag = MGLAnnotationTagNotFound;
_annotationsNearbyLastTap = {};
- _automaticallyAdjustContentInset = YES;
+ // TODO: This warning should be removed when automaticallyAdjustsScrollViewInsets is removed from
+ // the UIViewController api.
+ NSLog(@"%@ WARNING UIViewController.automaticallyAdjustsScrollViewInsets is deprecated use MGLMapView.automaticallyAdjustContentInset instead.",
+ NSStringFromClass(self.class));
// setup logo
//
@@ -840,11 +844,26 @@ public:
NSMutableArray *updatedConstraints = [NSMutableArray array];
UIEdgeInsets inset = UIEdgeInsetsZero;
- if (! self.automaticallyAdjustContentInset) {
+ BOOL automaticallyAdjustContentInset;
+ if (_automaticallyAdjustContentInsetHolder) {
+ automaticallyAdjustContentInset = _automaticallyAdjustContentInsetHolder.boolValue;
+ } else {
+ UIViewController *viewController = [self rootViewController];
+ automaticallyAdjustContentInset = viewController.automaticallyAdjustsScrollViewInsets;
+ }
+
+ if (! 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);
+
+ // makes sure the insets don't have negative values that could hide the ornaments
+ // thus violating our ToS
+ inset = UIEdgeInsetsMake(fmaxf(inset.top, 0),
+ fmaxf(inset.left, 0),
+ fmaxf(inset.bottom, 0),
+ fmaxf(inset.right, 0));
}
switch (position) {
@@ -982,28 +1001,13 @@ public:
- (void)adjustContentInset
{
UIEdgeInsets adjustedContentInsets = UIEdgeInsetsZero;
-
+ UIViewController *viewController = [self rootViewController];
+ BOOL automaticallyAdjustContentInset;
if (@available(iOS 11.0, *))
{
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)
@@ -1012,8 +1016,14 @@ public:
}
+ if (_automaticallyAdjustContentInsetHolder) {
+ automaticallyAdjustContentInset = _automaticallyAdjustContentInsetHolder.boolValue;
+ } else {
+ automaticallyAdjustContentInset = viewController.automaticallyAdjustsScrollViewInsets;
+ }
+
self.safeMapViewContentInsets = adjustedContentInsets;
- if ( ! self.automaticallyAdjustContentInset)
+ if ( ! automaticallyAdjustContentInset)
{
return;
}
@@ -1021,6 +1031,34 @@ public:
self.contentInset = adjustedContentInsets;
}
+- (UIViewController *)rootViewController {
+ // 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;
+ }
+ return viewController;
+}
+
+- (void)setAutomaticallyAdjustContentInset:(BOOL)automaticallyAdjustContentInset {
+ MGLLogDebug(@"Setting automaticallyAdjustContentInset: %@", MGLStringFromBOOL(automaticallyAdjustContentInset));
+ _automaticallyAdjustContentInsetHolder = [NSNumber numberWithBool:automaticallyAdjustContentInset];
+}
+
+- (BOOL)automaticallyAdjustContentInset {
+ return _automaticallyAdjustContentInsetHolder.boolValue;
+}
+
- (void)setContentInset:(UIEdgeInsets)contentInset
{
[self setContentInset:contentInset animated:NO completionHandler:nil];
@@ -1033,12 +1071,6 @@ 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))
{
diff --git a/platform/ios/test/MGLMapViewContentInsetTests.m b/platform/ios/test/MGLMapViewContentInsetTests.m
index 6ec669d847..8a4a74ceb3 100644
--- a/platform/ios/test/MGLMapViewContentInsetTests.m
+++ b/platform/ios/test/MGLMapViewContentInsetTests.m
@@ -100,7 +100,7 @@
XCTAssertTrue(CGPointEqualToPoint(attributionView.frame.origin, expectedAttributionOrigin));
UIEdgeInsets insets = UIEdgeInsetsMake(15, 10, 20, 5);
- self.mapView.automaticallyAdjustContentInset = NO;
+ self.viewController.automaticallyAdjustsScrollViewInsets = NO;
self.mapView.contentInset = insets;
[self.mapView setNeedsLayout];
@@ -144,6 +144,34 @@
y = self.screenBounds.size.height - attributionView.bounds.size.height - margin;
expectedAttributionOrigin = CGPointMake(x, y);
XCTAssertTrue(CGPointEqualToPoint(attributionView.frame.origin, expectedAttributionOrigin));
+
+ self.mapView.automaticallyAdjustContentInset = YES;
+ insets = UIEdgeInsetsMake(100, 100, 100, 100);
+ self.mapView.contentInset = insets;
+ XCTAssertTrue(UIEdgeInsetsEqualToEdgeInsets(self.mapView.contentInset, insets));
+
+ [self.mapView setNeedsLayout];
+ [self.mapView layoutIfNeeded];
+
+ // when automaticallyAdjustContentInset = YES the content insets should be overwrited
+ XCTAssertFalse(UIEdgeInsetsEqualToEdgeInsets(self.mapView.contentInset, insets));
+
+ expectedScaleBarOrigin = CGPointMake(margin, margin);
+ XCTAssertTrue(CGPointEqualToPoint(scaleBar.frame.origin, expectedScaleBarOrigin));
+
+ x = self.screenBounds.size.width - compassView.bounds.size.width - margin;
+ expectedCompassOrigin = CGPointMake(x, margin);
+ XCTAssertTrue(CGPointEqualToPoint(compassView.frame.origin, expectedCompassOrigin));
+
+ y = self.screenBounds.size.height - logoView.bounds.size.height - margin;
+ expectedLogoOrigin = CGPointMake(margin, y);
+ XCTAssertTrue(CGPointEqualToPoint(logoView.frame.origin, expectedLogoOrigin));
+
+ x = self.screenBounds.size.width - attributionView.bounds.size.width - margin;
+ y = self.screenBounds.size.height - attributionView.bounds.size.height - margin;
+ expectedAttributionOrigin = CGPointMake(x, y);
+ XCTAssertTrue(CGPointEqualToPoint(attributionView.frame.origin, expectedAttributionOrigin));
+
}
@end