diff options
Diffstat (limited to 'platform/macos')
-rw-r--r-- | platform/macos/CHANGELOG.md | 1 | ||||
-rw-r--r-- | platform/macos/src/MGLMapView.mm | 32 | ||||
-rw-r--r-- | platform/macos/src/MGLMapViewDelegate.h | 22 |
3 files changed, 55 insertions, 0 deletions
diff --git a/platform/macos/CHANGELOG.md b/platform/macos/CHANGELOG.md index eb06c36e36..dc2c93a64a 100644 --- a/platform/macos/CHANGELOG.md +++ b/platform/macos/CHANGELOG.md @@ -34,6 +34,7 @@ * Fixed an issue where translucent point annotations along tile boundaries would be drawn darker than expected. ([#6832](https://github.com/mapbox/mapbox-gl-native/pull/6832)) * Fixed flickering that occurred when panning past the antimeridian. ([#7574](https://github.com/mapbox/mapbox-gl-native/pull/7574)) +* Added a method to MGLMapViewDelegate, `-mapView:shouldChangeFromCamera:toCamera:`, that you can implement to restrict which parts the user can navigate to using gestures. ([#5584](https://github.com/mapbox/mapbox-gl-native/pull/5584)) * Added a `MGLDistanceFormatter` class for formatting geographic distances. ([#7888](https://github.com/mapbox/mapbox-gl-native/pull/7888)) ## 0.3.1 diff --git a/platform/macos/src/MGLMapView.mm b/platform/macos/src/MGLMapView.mm index d687a19aed..3d5f71feb1 100644 --- a/platform/macos/src/MGLMapView.mm +++ b/platform/macos/src/MGLMapView.mm @@ -995,8 +995,13 @@ public: - (void)offsetCenterCoordinateBy:(NSPoint)delta animated:(BOOL)animated { [self willChangeValueForKey:@"centerCoordinate"]; _mbglMap->cancelTransitions(); + MGLMapCamera *oldCamera = self.camera; _mbglMap->moveBy({ delta.x, delta.y }, MGLDurationInSecondsFromTimeInterval(animated ? MGLAnimationDuration : 0)); + if ([self.delegate respondsToSelector:@selector(mapView:shouldChangeFromCamera:toCamera:)] + && ![self.delegate mapView:self shouldChangeFromCamera:oldCamera toCamera:self.camera]) { + self.camera = oldCamera; + } [self didChangeValueForKey:@"centerCoordinate"]; } @@ -1043,8 +1048,13 @@ public: - (void)scaleBy:(double)scaleFactor atPoint:(NSPoint)point animated:(BOOL)animated { [self willChangeValueForKey:@"centerCoordinate"]; [self willChangeValueForKey:@"zoomLevel"]; + MGLMapCamera *oldCamera = self.camera; mbgl::ScreenCoordinate center(point.x, self.bounds.size.height - point.y); _mbglMap->scaleBy(scaleFactor, center, MGLDurationInSecondsFromTimeInterval(animated ? MGLAnimationDuration : 0)); + if ([self.delegate respondsToSelector:@selector(mapView:shouldChangeFromCamera:toCamera:)] + && ![self.delegate mapView:self shouldChangeFromCamera:oldCamera toCamera:self.camera]) { + self.camera = oldCamera; + } [self didChangeValueForKey:@"zoomLevel"]; [self didChangeValueForKey:@"centerCoordinate"]; } @@ -1379,15 +1389,25 @@ public: _directionAtBeginningOfGesture = self.direction; _pitchAtBeginningOfGesture = _mbglMap->getPitch(); } else if (gestureRecognizer.state == NSGestureRecognizerStateChanged) { + MGLMapCamera *oldCamera = self.camera; + BOOL didChangeCamera = NO; mbgl::ScreenCoordinate center(startPoint.x, self.bounds.size.height - startPoint.y); if (self.rotateEnabled) { CLLocationDirection newDirection = _directionAtBeginningOfGesture - delta.x / 10; [self willChangeValueForKey:@"direction"]; _mbglMap->setBearing(newDirection, center); + didChangeCamera = YES; [self didChangeValueForKey:@"direction"]; } if (self.pitchEnabled) { _mbglMap->setPitch(_pitchAtBeginningOfGesture + delta.y / 5, center); + didChangeCamera = YES; + } + + if (didChangeCamera + && [self.delegate respondsToSelector:@selector(mapView:shouldChangeFromCamera:toCamera:)] + && ![self.delegate mapView:self shouldChangeFromCamera:oldCamera toCamera:self.camera]) { + self.camera = oldCamera; } } } else if (self.scrollEnabled) { @@ -1427,7 +1447,12 @@ public: if (gestureRecognizer.magnification > -1) { [self willChangeValueForKey:@"zoomLevel"]; [self willChangeValueForKey:@"centerCoordinate"]; + MGLMapCamera *oldCamera = self.camera; _mbglMap->setScale(_scaleAtBeginningOfGesture * (1 + gestureRecognizer.magnification), center); + if ([self.delegate respondsToSelector:@selector(mapView:shouldChangeFromCamera:toCamera:)] + && ![self.delegate mapView:self shouldChangeFromCamera:oldCamera toCamera:self.camera]) { + self.camera = oldCamera; + } [self didChangeValueForKey:@"centerCoordinate"]; [self didChangeValueForKey:@"zoomLevel"]; } @@ -1502,9 +1527,16 @@ public: _mbglMap->setGestureInProgress(true); _directionAtBeginningOfGesture = self.direction; } else if (gestureRecognizer.state == NSGestureRecognizerStateChanged) { + MGLMapCamera *oldCamera = self.camera; + NSPoint rotationPoint = [gestureRecognizer locationInView:self]; mbgl::ScreenCoordinate center(rotationPoint.x, self.bounds.size.height - rotationPoint.y); _mbglMap->setBearing(_directionAtBeginningOfGesture + gestureRecognizer.rotationInDegrees, center); + + if ([self.delegate respondsToSelector:@selector(mapView:shouldChangeFromCamera:toCamera:)] + && ![self.delegate mapView:self shouldChangeFromCamera:oldCamera toCamera:self.camera]) { + self.camera = oldCamera; + } } else if (gestureRecognizer.state == NSGestureRecognizerStateEnded || gestureRecognizer.state == NSGestureRecognizerStateCancelled) { _mbglMap->setGestureInProgress(false); diff --git a/platform/macos/src/MGLMapViewDelegate.h b/platform/macos/src/MGLMapViewDelegate.h index 534e28e3a8..08a9f7eff4 100644 --- a/platform/macos/src/MGLMapViewDelegate.h +++ b/platform/macos/src/MGLMapViewDelegate.h @@ -61,6 +61,28 @@ NS_ASSUME_NONNULL_BEGIN */ - (void)mapView:(MGLMapView *)mapView cameraDidChangeAnimated:(BOOL)animated; +/** + Asks the delegate whether the map view should be allowed to change from the + existing camera to the new camera in response to a user gesture. + + This method is called as soon as the user gesture is recognized. It is not + called in response to a programmatic camera change, such as by setting the + `centerCoordinate` property or calling `-flyToCamera:completionHandler:`. + + This method is called many times during gesturing, so you should avoid performing + complex or performance-intensive tasks in your implementation. + + @param mapView The map view that the user is manipulating. + @param oldCamera The camera representing the viewpoint at the moment the + gesture is recognized. If this method returns `NO`, the map view’s camera + continues to be this camera. + @param newCamera The expected camera after the gesture completes. If this + method returns `YES`, this camera becomes the map view’s camera. + @return A Boolean value indicating whether the map view should stay at + `oldCamera` or change to `newCamera`. + */ +- (BOOL)mapView:(MGLMapView *)mapView shouldChangeFromCamera:(MGLMapCamera *)oldCamera toCamera:(MGLMapCamera *)newCamera; + #pragma mark Loading the Map /** |