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

[ios] Fix pinch drift ignoring delegate camera change response #11423

Merged
merged 2 commits into from
Mar 12, 2018
Merged
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 @@ -4,6 +4,7 @@ Mapbox welcomes participation and contributions from everyone. Please read [CONT

## 3.7.6

* Fixed an issue where the pinch gesture could drift beyond bounds imposed by `-[MGLMapViewDelegate mapView:shouldChangeFromCamera:toCamera:]`. ([#11423](https://github.com/mapbox/mapbox-gl-native/pull/11423))
* Improved the visibility of the heading indicator arrow. ([#11337](https://github.com/mapbox/mapbox-gl-native/pull/11337))

## 3.7.5 - February 16, 2018
Expand Down
43 changes: 42 additions & 1 deletion platform/ios/app/MBXViewController.m
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,11 @@
{ .latitude = -13.15589555, .longitude = -74.2178961777998 },
};

static const MGLCoordinateBounds colorado = {
.sw = { .latitude = 36.986207, .longitude = -109.049896},
.ne = { .latitude = 40.989329, .longitude = -102.062592},
};

static NSString * const MBXViewControllerAnnotationViewReuseIdentifer = @"MBXViewControllerAnnotationViewReuseIdentifer";

typedef NS_ENUM(NSInteger, MBXSettingsSections) {
Expand Down Expand Up @@ -85,6 +90,7 @@ typedef NS_ENUM(NSInteger, MBXSettingsMiscellaneousRows) {
MBXSettingsMiscellaneousToggleTwoMaps,
MBXSettingsMiscellaneousCountryLabels,
MBXSettingsMiscellaneousShowSnapshots,
MBXSettingsMiscellaneousShouldLimitCameraChanges,
MBXSettingsMiscellaneousPrintLogFile,
MBXSettingsMiscellaneousDeleteLogFile,
};
Expand Down Expand Up @@ -122,6 +128,7 @@ @interface MBXViewController () <UITableViewDelegate,
@property (nonatomic) BOOL usingLocaleBasedCountryLabels;
@property (nonatomic) BOOL reuseQueueStatsEnabled;
@property (nonatomic) BOOL showZoomLevelEnabled;
@property (nonatomic) BOOL shouldLimitCameraChanges;

@end

Expand Down Expand Up @@ -363,7 +370,8 @@ - (void)dismissSettings:(__unused id)sender
@"Embedded Map View",
[NSString stringWithFormat:@"%@ Second Map", ([self.view viewWithTag:2] == nil ? @"Show" : @"Hide")],
[NSString stringWithFormat:@"Show Labels in %@", (_usingLocaleBasedCountryLabels ? @"Default Language" : [[NSLocale currentLocale] displayNameForKey:NSLocaleIdentifier value:[self bestLanguageForUser]])],
@"Show Snapshots"
@"Show Snapshots",
[NSString stringWithFormat:@"%@ Camera Changes", (_shouldLimitCameraChanges ? @"Unlimit" : @"Limit")],
]];

if (self.debugLoggingEnabled)
Expand Down Expand Up @@ -652,6 +660,14 @@ - (void)performActionForSettingAtIndexPath:(NSIndexPath *)indexPath
[self performSegueWithIdentifier:@"ShowSnapshots" sender:nil];
break;
}
case MBXSettingsMiscellaneousShouldLimitCameraChanges:
{
self.shouldLimitCameraChanges = !self.shouldLimitCameraChanges;
if (self.shouldLimitCameraChanges) {
[self.mapView setCenterCoordinate:CLLocationCoordinate2DMake(39.748947, -104.995882) zoomLevel:10 direction:0 animated:NO];
}
break;
}
default:
NSAssert(NO, @"All miscellaneous setting rows should be implemented");
break;
Expand Down Expand Up @@ -1880,6 +1896,31 @@ - (void)mapView:(MGLMapView *)mapView didFinishLoadingStyle:(MGLStyle *)style
_usingLocaleBasedCountryLabels = [[self bestLanguageForUser] isEqualToString:@"en"];
}

- (BOOL)mapView:(MGLMapView *)mapView shouldChangeFromCamera:(MGLMapCamera *)oldCamera toCamera:(MGLMapCamera *)newCamera {
if (_shouldLimitCameraChanges) {
// Get the current camera to restore it after.
MGLMapCamera *currentCamera = mapView.camera;

// From the new camera obtain the center to test if it’s inside the boundaries.
CLLocationCoordinate2D newCameraCenter = newCamera.centerCoordinate;

// Set the map’s visible bounds to newCamera.
mapView.camera = newCamera;
MGLCoordinateBounds newVisibleCoordinates = mapView.visibleCoordinateBounds;

// Revert the camera.
mapView.camera = currentCamera;

// Test if the newCameraCenter and newVisibleCoordinates are inside Colorado.
BOOL inside = MGLCoordinateInCoordinateBounds(newCameraCenter, colorado);
BOOL intersects = MGLCoordinateInCoordinateBounds(newVisibleCoordinates.ne, colorado) && MGLCoordinateInCoordinateBounds(newVisibleCoordinates.sw, colorado);

return inside && intersects;
} else {
return YES;
}
}

- (void)mapViewRegionIsChanging:(MGLMapView *)mapView
{
[self updateHUD];
Expand Down
10 changes: 7 additions & 3 deletions platform/ios/src/MGLMapView.mm
Original file line number Diff line number Diff line change
Expand Up @@ -1459,10 +1459,12 @@ - (void)handlePinchGesture:(UIPinchGestureRecognizer *)pinch
double zoom = log2(newScale);
MGLMapCamera *toCamera = [self cameraByZoomingToZoomLevel:zoom aroundAnchorPoint:centerPoint];

if ([self _shouldChangeFromCamera:oldCamera toCamera:toCamera])
if ( ! [self _shouldChangeFromCamera:oldCamera toCamera:toCamera])
Copy link
Contributor Author

@friedbunny friedbunny Mar 8, 2018

Choose a reason for hiding this comment

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

This is (obviously) the key line — if the response from the delegate is NO we shouldn’t drift. Previously, this would always allow drifting because, if the delegate responded NO it would move on to the following else.

{
drift = NO;
} else {
}
else
{
if (drift)
{
_mbglMap->setZoom(zoom, mbgl::ScreenCoordinate { centerPoint.x, centerPoint.y }, MGLDurationFromTimeInterval(duration));
Expand Down Expand Up @@ -1695,7 +1697,9 @@ - (void)handleDoubleTapGesture:(UITapGestureRecognizer *)doubleTap
{
[weakSelf unrotateIfNeededForGesture];
}];
} else {
}
else
{
[self unrotateIfNeededForGesture];
}
}
Expand Down