From 012e88cc9b069f62824d9072ca3ede6a3c37d04b Mon Sep 17 00:00:00 2001 From: Jesse Bounds Date: Thu, 1 Jun 2017 10:53:02 -0700 Subject: [ios] Make annotation view rotation alignment configurable (#9147) This commit adds `rotatesWithMap` property on `MGLAnnotationView`. This property, when set to `YES` fixes the annotation to a map such that view follows map's rotation angle. This is useful when user wants to display rotation-dependent annotations (e.g. sector lights). --- platform/ios/CHANGELOG.md | 1 + platform/ios/src/MGLAnnotationView.h | 13 +++++++++++++ platform/ios/src/MGLAnnotationView.mm | 24 ++++++++++++++++++++++++ 3 files changed, 38 insertions(+) diff --git a/platform/ios/CHANGELOG.md b/platform/ios/CHANGELOG.md index 7228a94649..c57063707a 100644 --- a/platform/ios/CHANGELOG.md +++ b/platform/ios/CHANGELOG.md @@ -26,6 +26,7 @@ Mapbox welcomes participation and contributions from everyone. Please read [CONT ### Annotations * Added a new initializer to `MGLAnnotationView` so that it is possible to create a new instance with an associated annotation object. ([#9029](https://github.com/mapbox/mapbox-gl-native/pull/9029)) +* Added a new `rotatesToMatchCamera` property to `MGLAnnotationView` that, when set to true, causes the annotation view to rotate along with the map's rotation angle giving the appearance that the annoation view is pinned to the map. ([#9147](https://github.com/mapbox/mapbox-gl-native/pull/9147)) * Fixed an issue causing a view-backed annotation to disappear immediately instead of animating when the annotation’s `coordinate` property is set to a value outside the current viewport. ([#8565](https://github.com/mapbox/mapbox-gl-native/pull/8565)) * Fixed an issue in which `MGLMapView` overrode the tint colors of its annotation views. ([#8789](https://github.com/mapbox/mapbox-gl-native/pull/8789)) * Fixed an issue causing annotation views to persist in the map’s annotation container view even after their associated annotations were removed. ([#9025](https://github.com/mapbox/mapbox-gl-native/pull/9025)) diff --git a/platform/ios/src/MGLAnnotationView.h b/platform/ios/src/MGLAnnotationView.h index 9b17f05a6e..2802d31b05 100644 --- a/platform/ios/src/MGLAnnotationView.h +++ b/platform/ios/src/MGLAnnotationView.h @@ -171,6 +171,19 @@ typedef NS_ENUM(NSUInteger, MGLAnnotationViewDragState) { */ @property (nonatomic, assign) BOOL scalesWithViewingDistance; +/** + A Boolean value that determines whether the annotation view rotates together + with the map. + + When the value of this property is `YES` and the map is rotated, the annotation + view rotates. This is also the behavior of `MGLAnnotationImage` objects. When the + value of this property is `NO` the annotation has its rotation angle fixed. + + The default value of this property is `NO`. Set this property to `YES` if the + view’s rotation is important. + */ +@property (nonatomic, assign) BOOL rotatesToMatchCamera; + #pragma mark Managing the Selection State /** diff --git a/platform/ios/src/MGLAnnotationView.mm b/platform/ios/src/MGLAnnotationView.mm index 78e38f10cb..94d0649413 100644 --- a/platform/ios/src/MGLAnnotationView.mm +++ b/platform/ios/src/MGLAnnotationView.mm @@ -11,6 +11,7 @@ @property (nonatomic, readwrite, nullable) NSString *reuseIdentifier; @property (nonatomic, readwrite) CATransform3D lastAppliedScaleTransform; +@property (nonatomic, readwrite) CATransform3D lastAppliedRotateTransform; @property (nonatomic, weak) UIPanGestureRecognizer *panGestureRecognizer; @property (nonatomic, weak) UILongPressGestureRecognizer *longPressRecognizer; @property (nonatomic, weak) MGLMapView *mapView; @@ -53,6 +54,7 @@ _annotation = [decoder decodeObjectOfClass:[NSObject class] forKey:@"annotation"]; _centerOffset = [decoder decodeCGVectorForKey:@"centerOffset"]; _scalesWithViewingDistance = [decoder decodeBoolForKey:@"scalesWithViewingDistance"]; + _rotatesToMatchCamera = [decoder decodeBoolForKey:@"rotatesToMatchCamera"]; _selected = [decoder decodeBoolForKey:@"selected"]; _enabled = [decoder decodeBoolForKey:@"enabled"]; self.draggable = [decoder decodeBoolForKey:@"draggable"]; @@ -66,6 +68,7 @@ [coder encodeObject:_annotation forKey:@"annotation"]; [coder encodeCGVector:_centerOffset forKey:@"centerOffset"]; [coder encodeBool:_scalesWithViewingDistance forKey:@"scalesWithViewingDistance"]; + [coder encodeBool:_rotatesToMatchCamera forKey:@"rotatesToMatchCamera"]; [coder encodeBool:_selected forKey:@"selected"]; [coder encodeBool:_enabled forKey:@"enabled"]; [coder encodeBool:_draggable forKey:@"draggable"]; @@ -109,6 +112,7 @@ super.center = center; [self updateScaleTransformForViewingDistance]; + [self updateRotateTransform]; } - (void)setScalesWithViewingDistance:(BOOL)scalesWithViewingDistance @@ -157,6 +161,26 @@ } } +- (void)setRotatesToMatchCamera:(BOOL)rotatesToMatchCamera +{ + if (_rotatesToMatchCamera != rotatesToMatchCamera) + { + _rotatesToMatchCamera = rotatesToMatchCamera; + [self updateRotateTransform]; + } +} + +- (void)updateRotateTransform +{ + if (self.rotatesToMatchCamera == NO) return; + + CGFloat directionRad = self.mapView.direction * M_PI / 180.0; + CATransform3D newRotateTransform = CATransform3DMakeRotation(-directionRad, 0, 0, 1); + self.layer.transform = CATransform3DConcat(CATransform3DIdentity, newRotateTransform); + + _lastAppliedRotateTransform = newRotateTransform; +} + #pragma mark - Draggable - (void)setDraggable:(BOOL)draggable -- cgit v1.2.1