Skip to content
This repository has been archived by the owner on Jun 21, 2023. It is now read-only.

Adds a delegate to notify when a gesture is canceled. #284

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions platform/ios/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ Mapbox welcomes participation and contributions from everyone. Please read [CONT
* Fixed an issue where an `MGLMapSnapshotOptions` with an invalid `MGLMapCamera.centerCoordinate`, negative `MGLMapCamera.heading`, negative `MGLMapCamera.pitch`, and negative `MGLMapSnapshotOptions.zoomLevel` resulted in a snapshot centered on Null Island at zoom level 0 even if the style specified a different initial center coordinate or zoom level. ([#280](https://github.com/mapbox/mapbox-gl-native-ios/pull/280))
* Fixed an error that occurred if your implementation of the `-[MGLOfflineStorageDelegate offlineStorage:URLForResourceOfKind:]` method returned a local file URL. ([mapbox/mapbox-gl-native#16428](https://github.com/mapbox/mapbox-gl-native/pull/16428))
* Certain logging statements no longer run on the main thread. ([mapbox/mapbox-gl-native#16325](https://github.com/mapbox/mapbox-gl-native/pull/16325))
* Added the `-[MGLMapViewDelegate mapView:didCancelGestureForCamera:]` delegate method, which offers an opportunity to take action when the map canceled a gesture. ([#284](https://github.com/mapbox/mapbox-gl-native-ios/pull/284))

## 5.8.0

Expand Down
6 changes: 6 additions & 0 deletions platform/ios/app/MBXViewController.m
Original file line number Diff line number Diff line change
Expand Up @@ -2229,6 +2229,12 @@ - (BOOL)mapView:(MGLMapView *)mapView shouldChangeFromCamera:(MGLMapCamera *)old
}
}

- (void)mapView:(MGLMapView *)mapView didCancelGestureForCamera:(MGLMapCamera *)camera {
MGLMapCamera *toCamera = self.mapView.camera;
toCamera.centerCoordinate = CLLocationCoordinate2DMake(39.748947, -104.995882);
[self.mapView flyToCamera:toCamera withDuration:2.0 completionHandler:nil];
}

- (void)mapViewRegionIsChanging:(MGLMapView *)mapView
{
[self updateHUD];
Expand Down
30 changes: 28 additions & 2 deletions platform/ios/src/MGLMapView.mm
Original file line number Diff line number Diff line change
Expand Up @@ -1778,6 +1778,10 @@ - (void)handlePanGesture:(UIPanGestureRecognizer *)pan
default:
self.mbglMap.moveBy({ offset.x, offset.y }, MGLDurationFromTimeInterval(self.decelerationRate));
}
} else {
if ([self.delegate respondsToSelector:@selector(mapView:didCancelGestureForCamera:)]) {
[self.delegate mapView:self didCancelGestureForCamera:toCamera];
}
Comment on lines +1782 to +1784
Copy link
Contributor

@1ec5 1ec5 Apr 30, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if ([self.delegate respondsToSelector:@selector(mapView:didCancelGestureForCamera:)]) {
[self.delegate mapView:self didCancelGestureForCamera:toCamera];
}
MGLMapCamera *targetCamera = toCamera.copy;
if ([self.delegate respondsToSelector:@selector(mapViewWillEndPanning:targetCamera:)]) {
[self.delegate mapViewWillEndPanning:self targetCamera:targetCamera];
if (![toCamera isEqualToCamera:targetCamera]) {
[self setCamera:targetCamera animated:YES];
}
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, that would have to happen regardless of -mapView:shouldChangeFromCamera:toCamera:, so we’d move it out one level so it’s only conditionalized on drift.

}
}

Expand Down Expand Up @@ -1869,8 +1873,8 @@ - (void)handlePinchGesture:(UIPinchGestureRecognizer *)pinch
// Calculates the final camera zoom, this has no effect within current map camera.
double zoom = log2(newScale);
MGLMapCamera *toCamera = [self cameraByZoomingToZoomLevel:zoom aroundAnchorPoint:centerPoint];

if ( ! [self _shouldChangeFromCamera:oldCamera toCamera:toCamera])
BOOL shouldChange = [self _shouldChangeFromCamera:oldCamera toCamera:toCamera];
if ( ! shouldChange)
{
drift = NO;
}
Expand All @@ -1886,6 +1890,9 @@ - (void)handlePinchGesture:(UIPinchGestureRecognizer *)pinch
}

self.isZooming = NO;
if ( !shouldChange && [self.delegate respondsToSelector:@selector(mapView:didCancelGestureForCamera:)]) {
[self.delegate mapView:self didCancelGestureForCamera:toCamera];
}
[self notifyGestureDidEndWithDrift:drift];
[self unrotateIfNeededForGesture];
}
Expand Down Expand Up @@ -1999,6 +2006,10 @@ - (void)handleRotateGesture:(UIRotationGestureRecognizer *)rotate
{
[weakSelf unrotateIfNeededForGesture];
}];
} else {
if ([self.delegate respondsToSelector:@selector(mapView:didCancelGestureForCamera:)]) {
[self.delegate mapView:self didCancelGestureForCamera:toCamera];
}
}
}
else
Expand Down Expand Up @@ -2131,6 +2142,9 @@ - (void)handleDoubleTapGesture:(UITapGestureRecognizer *)doubleTap
}
else
{
if ([self.delegate respondsToSelector:@selector(mapView:didCancelGestureForCamera:)]) {
[self.delegate mapView:self didCancelGestureForCamera:toCamera];
}
[self unrotateIfNeededForGesture];
}
}
Expand Down Expand Up @@ -2169,6 +2183,10 @@ - (void)handleTwoFingerTapGesture:(UITapGestureRecognizer *)twoFingerTap
{
[weakSelf unrotateIfNeededForGesture];
}];
} else {
if ([self.delegate respondsToSelector:@selector(mapView:didCancelGestureForCamera:)]) {
[self.delegate mapView:self didCancelGestureForCamera:toCamera];
}
}
}

Expand Down Expand Up @@ -2207,6 +2225,10 @@ - (void)handleQuickZoomGesture:(UILongPressGestureRecognizer *)quickZoom
.withZoom(newZoom)
.withAnchor(mbgl::ScreenCoordinate { centerPoint.x, centerPoint.y })
.withPadding(MGLEdgeInsetsFromNSEdgeInsets(self.contentInset)));
} else {
if ([self.delegate respondsToSelector:@selector(mapView:didCancelGestureForCamera:)]) {
[self.delegate mapView:self didCancelGestureForCamera:toCamera];
}
}

[self cameraIsChanging];
Expand Down Expand Up @@ -2275,6 +2297,10 @@ - (void)handleTwoFingerDragGesture:(UIPanGestureRecognizer *)twoFingerDrag
.withPitch(pitchNew)
.withAnchor(mbgl::ScreenCoordinate { centerPoint.x, centerPoint.y })
.withPadding(MGLEdgeInsetsFromNSEdgeInsets(self.contentInset)));
} else {
if ([self.delegate respondsToSelector:@selector(mapView:didCancelGestureForCamera:)]) {
[self.delegate mapView:self didCancelGestureForCamera:toCamera];
}
}

[self cameraIsChanging];
Expand Down
16 changes: 16 additions & 0 deletions platform/ios/src/MGLMapViewDelegate.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,22 @@ NS_ASSUME_NONNULL_BEGIN
*/
- (BOOL)mapView:(MGLMapView *)mapView shouldChangeFromCamera:(MGLMapCamera *)oldCamera toCamera:(MGLMapCamera *)newCamera reason:(MGLCameraChangeReason)reason;

/**
Tells the delegate that the map view canceled a gesture.

This method is called as soon as `-mapView:shouldChangeFromCamera:toCamera:`
returns `NO`.

@param mapView The map view that the user is manipulating.
@param camera The camera that triggered a gesture cancellation.

#### Related examples
See the <a href="https://docs.mapbox.com/ios/maps/examples/constraining-gestures/">
Restrict map panning to an area</a> example to learn how to use this method
and `MGLMapCamera` objects to restrict a users ability to pan your map.
*/
- (void)mapView:(MGLMapView *)mapView didCancelGestureForCamera:(MGLMapCamera *)camera;

/**
Tells the delegate that the viewpoint depicted by the map view is about to change.

Expand Down
2 changes: 2 additions & 0 deletions platform/ios/test/MGLMapViewDelegateIntegrationTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,8 @@ extension MGLMapViewDelegateIntegrationTests: MGLMapViewDelegate {

func mapView(_ mapView: MGLMapView, shouldChangeFrom oldCamera: MGLMapCamera, to newCamera: MGLMapCamera, reason: MGLCameraChangeReason) -> Bool { return false }

func mapView(_ mapView: MGLMapView, didCancelGestureFor camera: MGLMapCamera) {}

func mapViewUserLocationAnchorPoint(_ mapView: MGLMapView) -> CGPoint { return CGPoint(x: 100, y: 100) }

func mapView(_ mapView: MGLMapView, didFailToLoadImage imageName: String) -> UIImage? { return nil }
Expand Down