summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFredrik Karlsson <bjorn.fredrik.karlsson@gmail.com>2017-05-19 14:01:35 +0200
committerGitHub <noreply@github.com>2017-05-19 14:01:35 +0200
commit3b109c8540ebd4da943e81beff5d9ae1483500c3 (patch)
tree178316de42245d12b3088e15ab7c61211d8abb70
parentf4f587f46dbde355bebd70e57cacf2ad788d0fd9 (diff)
downloadqtlocation-mapboxgl-3b109c8540ebd4da943e81beff5d9ae1483500c3.tar.gz
Observe layout guides (#7716)
* [ios] observe layout guides * [ios] update changelog
-rw-r--r--platform/ios/CHANGELOG.md1
-rw-r--r--platform/ios/src/MGLMapView.mm218
-rw-r--r--platform/ios/src/MGLScaleBar.mm6
3 files changed, 111 insertions, 114 deletions
diff --git a/platform/ios/CHANGELOG.md b/platform/ios/CHANGELOG.md
index 922b7b6486..ed3cb18b1b 100644
--- a/platform/ios/CHANGELOG.md
+++ b/platform/ios/CHANGELOG.md
@@ -32,6 +32,7 @@ Mapbox welcomes participation and contributions from everyone. Please read [CONT
* Fixed a crash or console spew when MGLMapView is initialized with a frame smaller than 64 points wide by 64 points tall. ([#8562](https://github.com/mapbox/mapbox-gl-native/pull/8562))
* The error passed into `-[MGLMapViewDelegate mapViewDidFailLoadingMap:withError:]` now includes a more specific description and failure reason. ([#8418](https://github.com/mapbox/mapbox-gl-native/pull/8418))
* Fixed an issue rendering polylines that contain duplicate vertices. ([#8808](https://github.com/mapbox/mapbox-gl-native/pull/8808))
+* Fixed a bug which caused the compass and other ornaments to underlap navigation and tab bars. ([#7716](https://github.com/mapbox/mapbox-gl-native/pull/7716))
## 3.5.2 - April 7, 2017
diff --git a/platform/ios/src/MGLMapView.mm b/platform/ios/src/MGLMapView.mm
index 4054099dbd..5acb600797 100644
--- a/platform/ios/src/MGLMapView.mm
+++ b/platform/ios/src/MGLMapView.mm
@@ -131,6 +131,9 @@ const CGFloat MGLAnnotationImagePaddingForCallout = 1;
const CGSize MGLAnnotationAccessibilityElementMinimumSize = CGSizeMake(10, 10);
+// Context for KVO observing UILayoutGuides.
+static void * MGLLayoutGuidesUpdatedContext = &MGLLayoutGuidesUpdatedContext;
+
/// Unique identifier representing a single annotation in mbgl.
typedef uint32_t MGLAnnotationTag;
@@ -233,13 +236,9 @@ public:
@property (nonatomic) GLKView *glView;
@property (nonatomic) UIImageView *glSnapshotView;
@property (nonatomic, readwrite) MGLScaleBar *scaleBar;
-@property (nonatomic) NS_MUTABLE_ARRAY_OF(NSLayoutConstraint *) *scaleBarConstraints;
@property (nonatomic, readwrite) UIImageView *compassView;
-@property (nonatomic) NS_MUTABLE_ARRAY_OF(NSLayoutConstraint *) *compassViewConstraints;
@property (nonatomic, readwrite) UIImageView *logoView;
-@property (nonatomic) NS_MUTABLE_ARRAY_OF(NSLayoutConstraint *) *logoViewConstraints;
@property (nonatomic, readwrite) UIButton *attributionButton;
-@property (nonatomic) NS_MUTABLE_ARRAY_OF(NSLayoutConstraint *) *attributionButtonConstraints;
@property (nonatomic, readwrite) MGLStyle *style;
@property (nonatomic) UITapGestureRecognizer *singleTapGestureRecognizer;
@property (nonatomic) UITapGestureRecognizer *doubleTap;
@@ -294,7 +293,8 @@ public:
NSDate *_userLocationAnimationCompletionDate;
/// True if a willChange notification has been issued for shape annotation layers and a didChange notification is pending.
BOOL _isChangingAnnotationLayers;
-
+ BOOL _isObservingTopLayoutGuide;
+ BOOL _isObservingBottomLayoutGuide;
BOOL _isWaitingForRedundantReachableNotification;
BOOL _isTargetingInterfaceBuilder;
@@ -471,9 +471,7 @@ public:
_logoView = [[UIImageView alloc] initWithImage:logo];
_logoView.accessibilityTraits = UIAccessibilityTraitStaticText;
_logoView.accessibilityLabel = NSLocalizedStringWithDefaultValue(@"LOGO_A11Y_LABEL", nil, nil, @"Mapbox", @"Accessibility label");
- _logoView.translatesAutoresizingMaskIntoConstraints = NO;
[self addSubview:_logoView];
- _logoViewConstraints = [NSMutableArray array];
// setup attribution
//
@@ -481,9 +479,7 @@ public:
_attributionButton.accessibilityLabel = NSLocalizedStringWithDefaultValue(@"INFO_A11Y_LABEL", nil, nil, @"About this map", @"Accessibility label");
_attributionButton.accessibilityHint = NSLocalizedStringWithDefaultValue(@"INFO_A11Y_HINT", nil, nil, @"Shows credits, a feedback form, and more", @"Accessibility hint");
[_attributionButton addTarget:self action:@selector(showAttribution) forControlEvents:UIControlEventTouchUpInside];
- _attributionButton.translatesAutoresizingMaskIntoConstraints = NO;
[self addSubview:_attributionButton];
- _attributionButtonConstraints = [NSMutableArray array];
[_attributionButton addObserver:self forKeyPath:@"hidden" options:NSKeyValueObservingOptionNew context:NULL];
// setup compass
@@ -495,16 +491,12 @@ public:
_compassView.accessibilityTraits = UIAccessibilityTraitButton;
_compassView.accessibilityLabel = NSLocalizedStringWithDefaultValue(@"COMPASS_A11Y_LABEL", nil, nil, @"Compass", @"Accessibility label");
_compassView.accessibilityHint = NSLocalizedStringWithDefaultValue(@"COMPASS_A11Y_HINT", nil, nil, @"Rotates the map to face due north", @"Accessibility hint");
- _compassView.translatesAutoresizingMaskIntoConstraints = NO;
[self addSubview:_compassView];
- _compassViewConstraints = [NSMutableArray array];
// setup scale control
//
_scaleBar = [[MGLScaleBar alloc] init];
- _scaleBar.translatesAutoresizingMaskIntoConstraints = NO;
[self addSubview:_scaleBar];
- _scaleBarConstraints = [NSMutableArray array];
// setup interaction
//
@@ -672,6 +664,14 @@ public:
[[NSNotificationCenter defaultCenter] removeObserver:self];
[_attributionButton removeObserver:self forKeyPath:@"hidden"];
+ if (_isObservingTopLayoutGuide) {
+ [(NSObject *)self.viewControllerForLayoutGuides.topLayoutGuide removeObserver:self forKeyPath:@"bounds" context:(void *)&MGLLayoutGuidesUpdatedContext];
+ }
+
+ if (_isObservingBottomLayoutGuide) {
+ [(NSObject *)self.viewControllerForLayoutGuides.bottomLayoutGuide removeObserver:self forKeyPath:@"bounds" context:(void *)&MGLLayoutGuidesUpdatedContext];
+ }
+
// Removing the annotations unregisters any outstanding KVO observers.
NSArray *annotations = self.annotations;
if (annotations)
@@ -697,11 +697,6 @@ public:
{
[EAGLContext setCurrentContext:nil];
}
-
- [self.logoViewConstraints removeAllObjects];
- self.logoViewConstraints = nil;
- [self.attributionButtonConstraints removeAllObjects];
- self.attributionButtonConstraints = nil;
}
- (void)setDelegate:(nullable id<MGLMapViewDelegate>)delegate
@@ -786,105 +781,31 @@ public:
- (void)updateConstraints
{
- // scale control
- //
- [self removeConstraints:self.scaleBarConstraints];
- [self.scaleBarConstraints removeAllObjects];
+ [super updateConstraints];
- [self.scaleBarConstraints addObject:
- [NSLayoutConstraint constraintWithItem:self.scaleBar
- attribute:NSLayoutAttributeTop
- relatedBy:NSLayoutRelationEqual
- toItem:self
- attribute:NSLayoutAttributeTop
- multiplier:1
- constant:5+self.contentInset.top]];
+ // If we have a view controller reference and its automaticallyAdjustsScrollViewInsets
+ // is set to YES, -[MGLMapView adjustContentInset] takes top and bottom layout
+ // guides into account. To get notified about changes to the layout guides,
+ // we need to observe their bounds and re-layout accordingly.
- [self.scaleBarConstraints addObject:
- [NSLayoutConstraint constraintWithItem:self.scaleBar
- attribute:NSLayoutAttributeLeading
- relatedBy:NSLayoutRelationEqual
- toItem:self
- attribute:NSLayoutAttributeLeading
- multiplier:1
- constant:8 + self.contentInset.left]];
+ UIViewController *viewController = self.viewControllerForLayoutGuides;
+ BOOL useLayoutGuides = viewController.view && viewController.automaticallyAdjustsScrollViewInsets;
- [self addConstraints:self.scaleBarConstraints];
+ if (useLayoutGuides && viewController.topLayoutGuide && !_isObservingTopLayoutGuide) {
+ [(NSObject *)viewController.topLayoutGuide addObserver:self forKeyPath:@"bounds" options:0 context:(void *)&MGLLayoutGuidesUpdatedContext];
+ _isObservingTopLayoutGuide = YES;
+ } else if (!useLayoutGuides && _isObservingTopLayoutGuide) {
+ [(NSObject *)viewController.topLayoutGuide removeObserver:self forKeyPath:@"bounds" context:(void *)&MGLLayoutGuidesUpdatedContext];
+ _isObservingTopLayoutGuide = NO;
+ }
- // compass
- //
- [self removeConstraints:self.compassViewConstraints];
- [self.compassViewConstraints removeAllObjects];
-
- [self.compassViewConstraints addObject:
- [NSLayoutConstraint constraintWithItem:self.compassView
- attribute:NSLayoutAttributeTop
- relatedBy:NSLayoutRelationEqual
- toItem:self
- attribute:NSLayoutAttributeTop
- multiplier:1
- constant:5 + self.contentInset.top]];
-
- [self.compassViewConstraints addObject:
- [NSLayoutConstraint constraintWithItem:self
- attribute:NSLayoutAttributeTrailing
- relatedBy:NSLayoutRelationEqual
- toItem:self.compassView
- attribute:NSLayoutAttributeTrailing
- multiplier:1
- constant:5 + self.contentInset.right]];
-
- [self addConstraints:self.compassViewConstraints];
-
- // logo bug
- //
- [self removeConstraints:self.logoViewConstraints];
- [self.logoViewConstraints removeAllObjects];
-
- [self.logoViewConstraints addObject:
- [NSLayoutConstraint constraintWithItem:self
- attribute:NSLayoutAttributeBottom
- relatedBy:NSLayoutRelationEqual
- toItem:self.logoView
- attribute:NSLayoutAttributeBaseline
- multiplier:1
- constant:8 + self.contentInset.bottom]];
-
- [self.logoViewConstraints addObject:
- [NSLayoutConstraint constraintWithItem:self.logoView
- attribute:NSLayoutAttributeLeading
- relatedBy:NSLayoutRelationEqual
- toItem:self
- attribute:NSLayoutAttributeLeading
- multiplier:1
- constant:8 + self.contentInset.left]];
- [self addConstraints:self.logoViewConstraints];
-
- // attribution button
- //
- [self removeConstraints:self.attributionButtonConstraints];
- [self.attributionButtonConstraints removeAllObjects];
-
- [self.attributionButtonConstraints addObject:
- [NSLayoutConstraint constraintWithItem:self
- attribute:NSLayoutAttributeBottom
- relatedBy:NSLayoutRelationEqual
- toItem:self.attributionButton
- attribute:NSLayoutAttributeBaseline
- multiplier:1
- constant:8 + self.contentInset.bottom]];
-
- [self.attributionButtonConstraints addObject:
- [NSLayoutConstraint constraintWithItem:self
- attribute:NSLayoutAttributeTrailing
- relatedBy:NSLayoutRelationEqual
- toItem:self.attributionButton
- attribute:NSLayoutAttributeTrailing
- multiplier:1
- constant:8 + self.contentInset.right]];
- [self addConstraints:self.attributionButtonConstraints];
-
- [super updateConstraints];
+ if (useLayoutGuides && viewController.bottomLayoutGuide && !_isObservingBottomLayoutGuide) {
+ [(NSObject *)viewController.bottomLayoutGuide addObserver:self forKeyPath:@"bounds" options:0 context:(void *)&MGLLayoutGuidesUpdatedContext];
+ _isObservingBottomLayoutGuide = YES;
+ } else if (!useLayoutGuides && _isObservingBottomLayoutGuide) {
+ [(NSObject *)viewController.bottomLayoutGuide removeObserver:self forKeyPath:@"bounds" context:(void *)&MGLLayoutGuidesUpdatedContext];
+ _isObservingBottomLayoutGuide = NO;
+ }
}
- (BOOL)isOpaque
@@ -917,6 +838,10 @@ public:
[super layoutSubviews];
[self adjustContentInset];
+
+ [self observeLayoutGuidesIfNeeded];
+
+ [self layoutOrnaments];
if (!_isTargetingInterfaceBuilder) {
_mbglMap->setSize([self size]);
@@ -931,6 +856,39 @@ public:
[self updateUserLocationAnnotationView];
}
+- (void)layoutOrnaments
+{
+ // scale bar
+ self.scaleBar.frame = {
+ self.contentInset.left+8,
+ self.contentInset.top+5,
+ CGRectGetWidth(self.scaleBar.frame),
+ CGRectGetHeight(self.scaleBar.frame)
+ };
+
+ // compass
+ self.compassView.center = {
+ .x = CGRectGetWidth(self.bounds)-CGRectGetMidX(self.compassView.bounds)-self.contentInset.right-5,
+ .y = CGRectGetMidY(self.compassView.bounds)+self.contentInset.top+5
+ };
+
+ // logo bug
+ self.logoView.frame = {
+ self.contentInset.left+5,
+ CGRectGetHeight(self.bounds)-5-self.contentInset.bottom-CGRectGetHeight(self.logoView.bounds),
+ CGRectGetWidth(self.logoView.bounds),
+ CGRectGetHeight(self.logoView.bounds)
+ };
+
+ // attribution
+ self.attributionButton.frame = {
+ CGRectGetWidth(self.bounds)-CGRectGetWidth(self.attributionButton.bounds)-self.contentInset.right-8,
+ CGRectGetHeight(self.bounds)-CGRectGetHeight(self.attributionButton.bounds)-self.contentInset.bottom-8,
+ CGRectGetWidth(self.attributionButton.bounds),
+ CGRectGetHeight(self.attributionButton.bounds)
+ };
+}
+
/// Updates `contentInset` to reflect the current window geometry.
- (void)adjustContentInset
{
@@ -970,6 +928,34 @@ public:
self.contentInset = contentInset;
}
+- (void)observeLayoutGuidesIfNeeded
+{
+ UIViewController *viewController = self.viewControllerForLayoutGuides;
+ BOOL useLayoutGuides = viewController.view && viewController.automaticallyAdjustsScrollViewInsets;
+
+ if (!_isObservingTopLayoutGuide && useLayoutGuides && viewController.topLayoutGuide)
+ {
+ [(NSObject *)viewController.topLayoutGuide addObserver:self forKeyPath:@"bounds" options:0 context:MGLLayoutGuidesUpdatedContext];
+ _isObservingTopLayoutGuide = YES;
+ }
+ else if (!useLayoutGuides && _isObservingTopLayoutGuide)
+ {
+ [(NSObject *)viewController.topLayoutGuide removeObserver:self forKeyPath:@"bounds" context:MGLLayoutGuidesUpdatedContext];
+ _isObservingTopLayoutGuide = NO;
+ }
+
+ if (!_isObservingBottomLayoutGuide && useLayoutGuides && viewController.bottomLayoutGuide)
+ {
+ [(NSObject *)viewController.bottomLayoutGuide addObserver:self forKeyPath:@"bounds" options:0 context:MGLLayoutGuidesUpdatedContext];
+ _isObservingBottomLayoutGuide = YES;
+ }
+ else if (!useLayoutGuides && _isObservingBottomLayoutGuide)
+ {
+ [(NSObject *)viewController.bottomLayoutGuide removeObserver:self forKeyPath:@"bounds" context:MGLLayoutGuidesUpdatedContext];
+ _isObservingBottomLayoutGuide = NO;
+ }
+}
+
- (void)setContentInset:(UIEdgeInsets)contentInset
{
[self setContentInset:contentInset animated:NO];
@@ -1000,7 +986,7 @@ public:
}
// Compass, logo and attribution button constraints needs to be updated.
- [self setNeedsUpdateConstraints];
+ [self setNeedsLayout];
}
/// Returns the frame of inset content within the map view.
@@ -2066,6 +2052,10 @@ public:
[self updateCalloutView];
}
}
+ else if (context == MGLLayoutGuidesUpdatedContext && [keyPath isEqualToString:@"bounds"])
+ {
+ [self setNeedsLayout];
+ }
}
+ (NS_SET_OF(NSString *) *)keyPathsForValuesAffectingZoomEnabled
diff --git a/platform/ios/src/MGLScaleBar.mm b/platform/ios/src/MGLScaleBar.mm
index 1216e400b3..cd88c1e08e 100644
--- a/platform/ios/src/MGLScaleBar.mm
+++ b/platform/ios/src/MGLScaleBar.mm
@@ -220,6 +220,12 @@ static const CGFloat MGLFeetPerMeter = 3.28084;
self.row = [self preferredRow];
+ CGSize size = self.intrinsicContentSize;
+ self.frame = CGRectMake(CGRectGetMinX(self.frame),
+ CGRectGetMinY(self.frame),
+ size.width,
+ size.height);
+
[self invalidateIntrinsicContentSize];
[self setNeedsLayout];
}