summaryrefslogtreecommitdiff
path: root/platform
diff options
context:
space:
mode:
authorMark Allen <mark.a.allen@gmail.com>2016-06-09 20:05:15 -0400
committerMinh Nguyễn <mxn@1ec5.org>2016-06-09 17:05:15 -0700
commitb915f05a069d4658cc11d91a4bae2ef52c5fcbf1 (patch)
tree358d1d9a82c27c81b0ebce732be0c08447b2c00b /platform
parent511801c17ab2dd47b11a84c6c23ed564dad04c29 (diff)
downloadqtlocation-mapboxgl-b915f05a069d4658cc11d91a4bae2ef52c5fcbf1.tar.gz
[ios] Support for a customizable zoom gesture centering strategy. (#5302)
* [ios] Support for a customizable zoom gesture centering strategy. We introduce a new MGLZoomGestureCentering enum and corresponding zoomGestureCentering property on MGLMapView. Currently, Mapbox automatically adjusts the center of the map relative to the user's gesture location, but for some applications (e.g Uber, Lyft) it is preferable to keep the map center "locked" in response to zoom gestures. Exisiting code will retain its current behavior without modification and will implicitly use the default value of MGLZoomGestureCenteringFollowsTouch. New code can specify MGLZoomGestureCenteringLockedInPlace to get the new "locked" behavior. * [ios] Added -anchorPointForGesture: to MGLMapView
Diffstat (limited to 'platform')
-rw-r--r--platform/ios/src/MGLMapView.h19
-rw-r--r--platform/ios/src/MGLMapView.mm54
2 files changed, 42 insertions, 31 deletions
diff --git a/platform/ios/src/MGLMapView.h b/platform/ios/src/MGLMapView.h
index 63d799bda9..09142c4093 100644
--- a/platform/ios/src/MGLMapView.h
+++ b/platform/ios/src/MGLMapView.h
@@ -763,6 +763,25 @@ IB_DESIGNABLE
- (MGLMapCamera *)cameraThatFitsCoordinateBounds:(MGLCoordinateBounds)bounds edgePadding:(UIEdgeInsets)insets;
/**
+ Returns the point in this view's coordinate system on which to "anchor" in
+ response to a user-initiated gesture.
+
+ For example, a pinch-to-zoom gesture would anchor the map at the midpoint of
+ the pinch.
+
+ If the `userTrackingMode` property is not `MGLUserTrackingModeNone`, the
+ user annotation is used as the anchor point.
+
+ Subclasses may override this method to provide specialized behavior - for
+ example, anchoring on the map's center point to provide a "locked" zooming
+ mode.
+
+ @param gesture An anchorable user gesture.
+ @return The point on which to anchor in response to the gesture.
+ */
+- (CGPoint)anchorPointForGesture:(UIGestureRecognizer *)gesture;
+
+/**
The distance from the edges of the map view’s frame to the edges of the map
view’s logical viewport.
diff --git a/platform/ios/src/MGLMapView.mm b/platform/ios/src/MGLMapView.mm
index 5d1bcb1109..4e304b23a5 100644
--- a/platform/ios/src/MGLMapView.mm
+++ b/platform/ios/src/MGLMapView.mm
@@ -1235,11 +1235,7 @@ mbgl::Duration MGLDurationInSeconds(NSTimeInterval duration)
_mbglMap->cancelTransitions();
- CGPoint centerPoint = [pinch locationInView:pinch.view];
- if (self.userTrackingMode != MGLUserTrackingModeNone)
- {
- centerPoint = self.userLocationAnnotationViewCenter;
- }
+ CGPoint centerPoint = [self anchorPointForGesture:pinch];
if (pinch.state == UIGestureRecognizerStateBegan)
{
@@ -1311,7 +1307,7 @@ mbgl::Duration MGLDurationInSeconds(NSTimeInterval duration)
[self unrotateIfNeededForGesture];
}
- _previousPinchCenterCoordinate = [self convertPoint:[pinch locationInView:pinch.view] toCoordinateFromView:self];
+ _previousPinchCenterCoordinate = [self convertPoint:centerPoint toCoordinateFromView:self];
_previousPinchNumberOfTouches = pinch.numberOfTouches;
}
@@ -1321,11 +1317,7 @@ mbgl::Duration MGLDurationInSeconds(NSTimeInterval duration)
_mbglMap->cancelTransitions();
- CGPoint centerPoint = [rotate locationInView:rotate.view];
- if (self.userTrackingMode != MGLUserTrackingModeNone)
- {
- centerPoint = self.userLocationAnnotationViewCenter;
- }
+ CGPoint centerPoint = [self anchorPointForGesture:rotate];
if (rotate.state == UIGestureRecognizerStateBegan)
{
@@ -1454,11 +1446,7 @@ mbgl::Duration MGLDurationInSeconds(NSTimeInterval duration)
if (doubleTap.state == UIGestureRecognizerStateEnded)
{
[self trackGestureEvent:MGLEventGestureDoubleTap forRecognizer:doubleTap];
- CGPoint gesturePoint = [doubleTap locationInView:doubleTap.view];
- if (self.userTrackingMode != MGLUserTrackingModeNone)
- {
- gesturePoint = self.userLocationAnnotationViewCenter;
- }
+ CGPoint gesturePoint = [self anchorPointForGesture:doubleTap];
mbgl::ScreenCoordinate center(gesturePoint.x, gesturePoint.y);
_mbglMap->scaleBy(2, center, MGLDurationInSeconds(MGLAnimationDuration));
@@ -1486,11 +1474,7 @@ mbgl::Duration MGLDurationInSeconds(NSTimeInterval duration)
}
else if (twoFingerTap.state == UIGestureRecognizerStateEnded)
{
- CGPoint gesturePoint = [twoFingerTap locationInView:twoFingerTap.view];
- if (self.userTrackingMode != MGLUserTrackingModeNone)
- {
- gesturePoint = self.userLocationAnnotationViewCenter;
- }
+ CGPoint gesturePoint = [self anchorPointForGesture:twoFingerTap];
mbgl::ScreenCoordinate center(gesturePoint.x, gesturePoint.y);
_mbglMap->scaleBy(0.5, center, MGLDurationInSeconds(MGLAnimationDuration));
@@ -1528,11 +1512,8 @@ mbgl::Duration MGLDurationInSeconds(NSTimeInterval duration)
if (newZoom < _mbglMap->getMinZoom()) return;
- CGPoint centerPoint = self.contentCenter;
- if (self.userTrackingMode != MGLUserTrackingModeNone)
- {
- centerPoint = self.userLocationAnnotationViewCenter;
- }
+ CGPoint centerPoint = [self anchorPointForGesture:quickZoom];
+
_mbglMap->scaleBy(powf(2, newZoom) / _mbglMap->getScale(),
mbgl::ScreenCoordinate { centerPoint.x, centerPoint.y });
@@ -1564,11 +1545,8 @@ mbgl::Duration MGLDurationInSeconds(NSTimeInterval duration)
CGFloat pitchNew = currentPitch - (gestureDistance / slowdown);
- CGPoint centerPoint = self.contentCenter;
- if (self.userTrackingMode != MGLUserTrackingModeNone)
- {
- centerPoint = self.userLocationAnnotationViewCenter;
- }
+ CGPoint centerPoint = [self anchorPointForGesture:twoFingerDrag];
+
_mbglMap->setPitch(pitchNew, mbgl::ScreenCoordinate { centerPoint.x, centerPoint.y });
[self notifyMapChange:mbgl::MapChangeRegionIsChanging];
@@ -1578,7 +1556,21 @@ mbgl::Duration MGLDurationInSeconds(NSTimeInterval duration)
[self notifyGestureDidEndWithDrift:NO];
[self unrotateIfNeededForGesture];
}
+}
+- (CGPoint)anchorPointForGesture:(UIGestureRecognizer *)gesture {
+ if (self.userTrackingMode != MGLUserTrackingModeNone)
+ {
+ return self.userLocationAnnotationViewCenter;
+ }
+
+ // Special case for two-finger drag and quickzoom
+ if ([gesture isKindOfClass:[UIPanGestureRecognizer class]] || [gesture isKindOfClass:[UILongPressGestureRecognizer class]])
+ {
+ return self.contentCenter;
+ }
+
+ return [gesture locationInView:gesture.view];
}
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer