summaryrefslogtreecommitdiff
path: root/platform/ios/src/MGLMapView.mm
diff options
context:
space:
mode:
Diffstat (limited to 'platform/ios/src/MGLMapView.mm')
-rw-r--r--platform/ios/src/MGLMapView.mm109
1 files changed, 64 insertions, 45 deletions
diff --git a/platform/ios/src/MGLMapView.mm b/platform/ios/src/MGLMapView.mm
index 9c3d1d415f..d9d03ea478 100644
--- a/platform/ios/src/MGLMapView.mm
+++ b/platform/ios/src/MGLMapView.mm
@@ -1116,8 +1116,10 @@ public:
- (void)updateTintColorForView:(UIView *)view
{
- // stop at recursing container & annotation views (#8522)
- if ([view isEqual:self.annotationContainerView]) return;
+ // Don't update:
+ // - annotation views
+ // - attribution button (handled automatically)
+ if ([view isEqual:self.annotationContainerView] || [view isEqual:self.attributionButton]) return;
if ([view respondsToSelector:@selector(setTintColor:)]) view.tintColor = self.tintColor;
@@ -1250,8 +1252,6 @@ public:
{
if ( ! self.isZoomEnabled) return;
- if (_mbglMap->getZoom() <= _mbglMap->getMinZoom() && pinch.scale < 1) return;
-
_mbglMap->cancelTransitions();
CGPoint centerPoint = [self anchorPointForGesture:pinch];
@@ -1267,17 +1267,17 @@ public:
}
else if (pinch.state == UIGestureRecognizerStateChanged)
{
+ // Zoom limiting happens at the core level.
CGFloat newScale = self.scale * pinch.scale;
- double zoom = log2(newScale);
- if (zoom < _mbglMap->getMinZoom()) return;
-
+ double newZoom = log2(newScale);
+
// Calculates the final camera zoom, has no effect within current map camera.
- MGLMapCamera *toCamera = [self cameraByZoomingToZoomLevel:zoom aroundAnchorPoint:centerPoint];
+ MGLMapCamera *toCamera = [self cameraByZoomingToZoomLevel:newZoom aroundAnchorPoint:centerPoint];
if (![self.delegate respondsToSelector:@selector(mapView:shouldChangeFromCamera:toCamera:)] ||
[self.delegate mapView:self shouldChangeFromCamera:oldCamera toCamera:toCamera])
{
- _mbglMap->setZoom(zoom, mbgl::ScreenCoordinate { centerPoint.x, centerPoint.y });
+ _mbglMap->setZoom(newZoom, mbgl::ScreenCoordinate { centerPoint.x, centerPoint.y });
// The gesture recognizer only reports the gesture’s current center
// point, so use the previous center point to anchor the transition.
// If the number of touches has changed, the remembered center point is
@@ -1625,9 +1625,9 @@ public:
{
CGFloat distance = [quickZoom locationInView:quickZoom.view].y - self.quickZoomStart;
- CGFloat newZoom = log2f(self.scale) + (distance / 75);
+ CGFloat newZoom = MAX(log2f(self.scale) + (distance / 75), _mbglMap->getMinZoom());
- if (newZoom < _mbglMap->getMinZoom()) return;
+ if (_mbglMap->getZoom() == newZoom) return;
CGPoint centerPoint = [self anchorPointForGesture:quickZoom];
@@ -1760,39 +1760,6 @@ public:
return [gesture locationInView:gesture.view];
}
-- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer
-{
- if ([gestureRecognizer isKindOfClass:[UIPanGestureRecognizer class]])
- {
- UIPanGestureRecognizer *panGesture = (UIPanGestureRecognizer *)gestureRecognizer;
-
- if (panGesture.minimumNumberOfTouches == 2)
- {
- CGPoint velocity = [panGesture velocityInView:panGesture.view];
- double gestureAngle = MGLDegreesFromRadians(atan(velocity.y / velocity.x));
- double horizontalToleranceDegrees = 20.0;
-
- // cancel if gesture angle is not 90º±20º (more or less vertical)
- if ( ! (fabs((fabs(gestureAngle) - 90.0)) < horizontalToleranceDegrees))
- {
- return NO;
- }
- }
- }
- else if (gestureRecognizer == _singleTapGestureRecognizer)
- {
- // Gesture will be recognized if it could deselect an annotation
- if(!self.selectedAnnotation)
- {
- id<MGLAnnotation>annotation = [self annotationForGestureRecognizer:(UITapGestureRecognizer*)gestureRecognizer persistingResults:NO];
- if(!annotation) {
- return NO;
- }
- }
- }
- return YES;
-}
-
- (void)handleCalloutAccessoryTapGesture:(UITapGestureRecognizer *)tap
{
if ([self.delegate respondsToSelector:@selector(mapView:annotation:calloutAccessoryControlTapped:)])
@@ -1836,12 +1803,60 @@ public:
UIAccessibilityPostNotification(UIAccessibilityLayoutChangedNotification, calloutView);
}
+- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer
+{
+ if ([gestureRecognizer isKindOfClass:[UIPanGestureRecognizer class]])
+ {
+ UIPanGestureRecognizer *panGesture = (UIPanGestureRecognizer *)gestureRecognizer;
+
+ if (panGesture.minimumNumberOfTouches == 2)
+ {
+ CGPoint west = [panGesture locationOfTouch:0 inView:panGesture.view];
+ CGPoint east = [panGesture locationOfTouch:1 inView:panGesture.view];
+
+ if (west.x > east.x) {
+ CGPoint swap = west;
+ west = east;
+ east = swap;
+ }
+
+ CLLocationDegrees horizontalToleranceDegrees = 60.0;
+ if ([self angleBetweenPoints:west east:east] > horizontalToleranceDegrees) {
+ return NO;
+ }
+
+ }
+ }
+ else if (gestureRecognizer == _singleTapGestureRecognizer)
+ {
+ // Gesture will be recognized if it could deselect an annotation
+ if(!self.selectedAnnotation)
+ {
+ id<MGLAnnotation>annotation = [self annotationForGestureRecognizer:(UITapGestureRecognizer*)gestureRecognizer persistingResults:NO];
+ if(!annotation) {
+ return NO;
+ }
+ }
+ }
+ return YES;
+}
+
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{
NSArray *validSimultaneousGestures = @[ self.pan, self.pinch, self.rotate ];
return ([validSimultaneousGestures containsObject:gestureRecognizer] && [validSimultaneousGestures containsObject:otherGestureRecognizer]);
}
+
+- (CLLocationDegrees)angleBetweenPoints:(CGPoint)west east:(CGPoint)east
+{
+ CGFloat slope = (west.y - east.y) / (west.x - east.x);
+
+ CGFloat angle = atan(fabs(slope));
+ CLLocationDegrees degrees = MGLDegreesFromRadians(angle);
+
+ return degrees;
+}
- (void)trackGestureEvent:(NSString *)gestureID forRecognizer:(UIGestureRecognizer *)recognizer
{
@@ -2743,6 +2758,10 @@ public:
- (void)setCamera:(MGLMapCamera *)camera withDuration:(NSTimeInterval)duration animationTimingFunction:(nullable CAMediaTimingFunction *)function completionHandler:(nullable void (^)(void))completion
{
+ [self setCamera:camera withDuration:duration animationTimingFunction:function edgePadding:self.contentInset completionHandler:completion];
+}
+
+- (void)setCamera:(MGLMapCamera *)camera withDuration:(NSTimeInterval)duration animationTimingFunction:(nullable CAMediaTimingFunction *)function edgePadding:(UIEdgeInsets)edgePadding completionHandler:(nullable void (^)(void))completion {
mbgl::AnimationOptions animationOptions;
if (duration > 0)
{
@@ -2771,7 +2790,7 @@ public:
[self willChangeValueForKey:@"camera"];
_mbglMap->cancelTransitions();
- mbgl::CameraOptions cameraOptions = [self cameraOptionsObjectForAnimatingToCamera:camera edgePadding:self.contentInset];
+ mbgl::CameraOptions cameraOptions = [self cameraOptionsObjectForAnimatingToCamera:camera edgePadding:edgePadding];
_mbglMap->easeTo(cameraOptions, animationOptions);
[self didChangeValueForKey:@"camera"];
}