summaryrefslogtreecommitdiff
path: root/platform/macos
diff options
context:
space:
mode:
Diffstat (limited to 'platform/macos')
-rw-r--r--platform/macos/CHANGELOG.md1
-rw-r--r--platform/macos/src/MGLMapView.mm32
-rw-r--r--platform/macos/src/MGLMapViewDelegate.h22
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
/**