From 2501b2cc7baaf0d2f62aa19298301d066dfab0ea Mon Sep 17 00:00:00 2001 From: "Justin R. Miller" Date: Thu, 25 Aug 2016 17:23:15 -0700 Subject: [PATCH] [ios] preserve annotation transforms during perspective scaling --- platform/ios/CHANGELOG.md | 1 + platform/ios/src/MGLAnnotationView.mm | 34 +++++++++++++-------------- 2 files changed, 17 insertions(+), 18 deletions(-) diff --git a/platform/ios/CHANGELOG.md b/platform/ios/CHANGELOG.md index b8a7f7e7498..3425c30bf31 100644 --- a/platform/ios/CHANGELOG.md +++ b/platform/ios/CHANGELOG.md @@ -39,6 +39,7 @@ Mapbox welcomes participation and contributions from everyone. Please read [CONT * To make an MGLPolyline or MGLPolygon span the antimeridian, specify coordinates with longitudes greater than 180° or less than −180°. ([#6088](https://github.com/mapbox/mapbox-gl-native/pull/6088)) * Improved the performance of relocating a non-view-backed point annotation by changing its `coordinate` property. ([#5385](https://github.com/mapbox/mapbox-gl-native/pull/5385)) * Improved the precision of annotations at zoom levels greater than 18. ([#5517](https://github.com/mapbox/mapbox-gl-native/pull/5517)) +* Fixed an issue that could reset user-added transformations on annotation views. ([#6166](https://github.com/mapbox/mapbox-gl-native/pull/6166)) ### Other changes diff --git a/platform/ios/src/MGLAnnotationView.mm b/platform/ios/src/MGLAnnotationView.mm index 705e55e6580..c37adc55664 100644 --- a/platform/ios/src/MGLAnnotationView.mm +++ b/platform/ios/src/MGLAnnotationView.mm @@ -11,6 +11,7 @@ @interface MGLAnnotationView () @property (nonatomic, readwrite, nullable) NSString *reuseIdentifier; @property (nonatomic, readwrite, nullable) id annotation; +@property (nonatomic, readwrite) CATransform3D lastAppliedScaleTransform; @property (nonatomic, weak) UIPanGestureRecognizer *panGestureRecognizer; @property (nonatomic, weak) UILongPressGestureRecognizer *longPressRecognizer; @property (nonatomic, weak) MGLMapView *mapView; @@ -24,6 +25,7 @@ - (instancetype)initWithReuseIdentifier:(NSString *)reuseIdentifier self = [self initWithFrame:CGRectZero]; if (self) { + _lastAppliedScaleTransform = CATransform3DIdentity; _reuseIdentifier = [reuseIdentifier copy]; _scalesWithViewingDistance = YES; _enabled = YES; @@ -68,7 +70,7 @@ - (void)setCenter:(CGPoint)center center.y += _centerOffset.dy; super.center = center; - [self updateTransform]; + [self updateScaleTransformForViewingDistance]; } - (void)setScalesWithViewingDistance:(BOOL)scalesWithViewingDistance @@ -76,24 +78,14 @@ - (void)setScalesWithViewingDistance:(BOOL)scalesWithViewingDistance if (_scalesWithViewingDistance != scalesWithViewingDistance) { _scalesWithViewingDistance = scalesWithViewingDistance; - [self updateTransform]; + [self updateScaleTransformForViewingDistance]; } } -- (void)updateTransform +- (void)updateScaleTransformForViewingDistance { - // Omit applying a new transformation while the view is being dragged. - if (self.dragState == MGLAnnotationViewDragStateDragging) - { - return; - } - - self.layer.transform = CATransform3DIdentity; - if ( ! self.scalesWithViewingDistance) - { - return; - } - + if (self.scalesWithViewingDistance == NO || self.dragState == MGLAnnotationViewDragStateDragging) return; + CGFloat superviewHeight = CGRectGetHeight(self.superview.frame); if (superviewHeight > 0.0) { // Find the maximum amount of scale reduction to apply as the view's center moves from the top @@ -115,9 +107,15 @@ - (void)updateTransform // map view is 50% pitched then the annotation view should be reduced by 37.5% (.75 * .5). The // reduction is then normalized for a scale of 1.0. CGFloat pitchAdjustedScale = 1.0 - maxScaleReduction * pitchIntensity; - - CATransform3D transform = CATransform3DIdentity; - self.layer.transform = CATransform3DScale(transform, pitchAdjustedScale, pitchAdjustedScale, 1); + + // We keep track of each viewing distance scale transform that we apply. Each iteration, + // we can account for it so that we don't get cumulative scaling every time we move. + // We also avoid clobbering any existing transform passed in by the client, too. + CATransform3D undoOfLastScaleTransform = CATransform3DInvert(_lastAppliedScaleTransform); + CATransform3D newScaleTransform = CATransform3DMakeScale(pitchAdjustedScale, pitchAdjustedScale, 1); + CATransform3D effectiveTransform = CATransform3DConcat(undoOfLastScaleTransform, newScaleTransform); + self.layer.transform = CATransform3DConcat(self.layer.transform, effectiveTransform); + _lastAppliedScaleTransform = newScaleTransform; } }