Skip to content
This repository has been archived by the owner on Aug 8, 2023. It is now read-only.

Make annotation view rotation alignment configurable #8308

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions platform/ios/src/MGLAnnotationView.h
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,19 @@ typedef NS_ENUM(NSUInteger, MGLAnnotationViewDragState) {
*/
@property (nonatomic, assign) BOOL scalesWithViewingDistance;

/**
A Boolean value that determines whether the annotation view rotates together
with the mapview.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: replace “mapview” with “map”, since the direction property reflects the rotation of the content within the map view, not the map view itself.


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 rotatesWithMap;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#5245 at one point called this property rotatesToMatchCamera, which I think would do a better job of describing exactly what it does. (After all, technically you could rotate the MGLMapView itself in 3D space! 😂)


#pragma mark Managing the Selection State

/**
Expand Down
28 changes: 28 additions & 0 deletions platform/ios/src/MGLAnnotationView.mm
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ @interface MGLAnnotationView () <UIGestureRecognizerDelegate>

@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;
Expand All @@ -25,8 +26,10 @@ - (instancetype)initWithReuseIdentifier:(NSString *)reuseIdentifier
if (self)
{
_lastAppliedScaleTransform = CATransform3DIdentity;
_lastAppliedRotateTransform = CATransform3DIdentity;
_reuseIdentifier = [reuseIdentifier copy];
_scalesWithViewingDistance = YES;
_rotatesWithMap = NO;
_enabled = YES;
}
return self;
Expand All @@ -42,6 +45,7 @@ - (instancetype)initWithCoder:(NSCoder *)decoder {
_annotation = [decoder decodeObjectOfClass:[NSObject class] forKey:@"annotation"];
_centerOffset = [decoder decodeCGVectorForKey:@"centerOffset"];
_scalesWithViewingDistance = [decoder decodeBoolForKey:@"scalesWithViewingDistance"];
_rotatesWithMap = [decoder decodeBoolForKey:@"rotatesWithMap"];
_selected = [decoder decodeBoolForKey:@"selected"];
_enabled = [decoder decodeBoolForKey:@"enabled"];
self.draggable = [decoder decodeBoolForKey:@"draggable"];
Expand All @@ -55,6 +59,7 @@ - (void)encodeWithCoder:(NSCoder *)coder {
[coder encodeObject:_annotation forKey:@"annotation"];
[coder encodeCGVector:_centerOffset forKey:@"centerOffset"];
[coder encodeBool:_scalesWithViewingDistance forKey:@"scalesWithViewingDistance"];
[coder encodeBool:_rotatesWithMap forKey:@"rotatesWithMap"];
[coder encodeBool:_selected forKey:@"selected"];
[coder encodeBool:_enabled forKey:@"enabled"];
[coder encodeBool:_draggable forKey:@"draggable"];
Expand Down Expand Up @@ -146,6 +151,29 @@ - (void)updateScaleTransformForViewingDistance
}
}

- (void)setRotatesWithMap:(BOOL)rotatesWithMap
{
if (_rotatesWithMap != rotatesWithMap)
{
_rotatesWithMap = rotatesWithMap;
[self updateRotateTransform];
}
}

- (void)updateRotateTransform
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As far as I can tell, this method only gets called when rotatesToMatchCamera is set explicitly by application code. But the annotation view’s transform matrix is always overridden whenever the map viewport changes. -updateScaleTransformForViewingDistance gets called by -setCenter:, which coincidentally happens to be the method that -[MGLMapView update AnnotationViews] calls to clobber reposition the annotation view to match the map. We could merge this method and -updateScaleTransformForViewingDistance into an -updateTransform method that comes up with the canonical transform to apply.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right. I was copy-pasting the code from my private repository that was used with the project. Forgot to add the call to [self updateRotateTransform]; from setCenter.

{
if (self.rotatesWithMap == NO) return;

CATransform3D undoOfLastRotateTransform = CATransform3DInvert(_lastAppliedRotateTransform);

CGFloat directionRad = self.mapView.direction * M_PI / 180.0;
CATransform3D newRotateTransform = CATransform3DMakeRotation(-directionRad, 0, 0, 1);
CATransform3D effectiveTransform = CATransform3DConcat(undoOfLastRotateTransform, newRotateTransform);

self.layer.transform = CATransform3DConcat(self.layer.transform, effectiveTransform);
_lastAppliedRotateTransform = newRotateTransform;
}

#pragma mark - Draggable

- (void)setDraggable:(BOOL)draggable
Expand Down