summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMinh Nguyễn <mxn@1ec5.org>2016-01-16 22:00:47 -0800
committerMinh Nguyễn <mxn@1ec5.org>2016-01-16 22:00:47 -0800
commitcb126eafe0e9b482162414d0fbbc0ae4d4f3cea9 (patch)
treeb62f341409eda494b90091d358119a573636128c
parented32fa06ed851618069126cc6717405d6710f05f (diff)
downloadqtlocation-mapboxgl-cb126eafe0e9b482162414d0fbbc0ae4d4f3cea9.tar.gz
[ios] Refactored unrotation
Avoid unrotating due to programmatic rotation, even programmatic rotation that might expose empty portions of the map. Only snap to north due to a gesture.
-rw-r--r--CHANGELOG.md2
-rw-r--r--platform/ios/src/MGLMapView.mm62
2 files changed, 35 insertions, 29 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index ae5ff8caf3..c93d0b2b43 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -46,7 +46,7 @@ Known issues:
- MGLMapCamera’s `altitude` values now match those of MKMapCamera. ([#3362](https://github.com/mapbox/mapbox-gl-native/pull/3362))
- The user dot’s callout view is now centered above the user dot. It was previously offset slightly to the left. ([#3261](https://github.com/mapbox/mapbox-gl-native/pull/3261))
- Fixed an issue with small map views not properly fitting annotations within bounds. (#[3407](https://github.com/mapbox/mapbox-gl-native/pull/3407))
-- The map will now snap to north. ([#3403](https://github.com/mapbox/mapbox-gl-native/pull/3403))
+- When the user rotates the map to within 7° of true north, the map view now snaps to true north. ([#3403](https://github.com/mapbox/mapbox-gl-native/pull/3403))
- The map view’s background can now be transparent or translucent, as long as the style’s background layer is transparent or translucent and `MGLMapView.opaque` is set to `NO`. ([#3096](https://github.com/mapbox/mapbox-gl-native/pull/3096))
- Documentation is now generated by [jazzy](https://github.com/realm/jazzy) instead of appledoc. ♪♫ ([#3203](https://github.com/mapbox/mapbox-gl-native/pull/3203))
- New API to provide a custom callout view to the map for annotations. ([#3456](https://github.com/mapbox/mapbox-gl-native/pull/3456))
diff --git a/platform/ios/src/MGLMapView.mm b/platform/ios/src/MGLMapView.mm
index 2269196c87..1bc725520e 100644
--- a/platform/ios/src/MGLMapView.mm
+++ b/platform/ios/src/MGLMapView.mm
@@ -55,6 +55,9 @@ const CGSize MGLAnnotationUpdateViewportOutset = {150, 150};
const CGFloat MGLMinimumZoom = 3;
const NSUInteger MGLTargetFrameInterval = 1; //Target FPS will be 60 divided by this value
+/// Tolerance for snapping to true north, measured in degrees in either direction.
+const CLLocationDirection MGLToleranceForSnappingToNorth = 7;
+
/// Reuse identifier and file name of the default point annotation image.
static NSString * const MGLDefaultStyleMarkerSymbolName = @"default_marker";
@@ -1086,7 +1089,7 @@ std::chrono::steady_clock::duration MGLDurationInSeconds(float duration)
[self notifyGestureDidEndWithDrift:velocity];
- [self unrotateIfNeededAnimated:YES];
+ [self unrotateIfNeededForGesture];
}
}
@@ -1143,14 +1146,13 @@ std::chrono::steady_clock::duration MGLDurationInSeconds(float duration)
[self animateWithDelay:duration animations:^
{
- [weakSelf unrotateIfNeededAnimated:YES];
+ [weakSelf unrotateIfNeededForGesture];
}];
}
else
{
[self notifyGestureDidEndWithDrift:NO];
-
- [self unrotateIfNeededAnimated:YES];
+ [self unrotateIfNeededForGesture];
}
}
}
@@ -1234,7 +1236,7 @@ std::chrono::steady_clock::duration MGLDurationInSeconds(float duration)
[self animateWithDelay:MGLAnimationDuration animations:^
{
- [weakSelf unrotateIfNeededAnimated:YES];
+ [weakSelf unrotateIfNeededForGesture];
}];
}
}
@@ -1273,7 +1275,7 @@ std::chrono::steady_clock::duration MGLDurationInSeconds(float duration)
[self animateWithDelay:MGLAnimationDuration animations:^
{
- [weakSelf unrotateIfNeededAnimated:YES];
+ [weakSelf unrotateIfNeededForGesture];
}];
}
}
@@ -1310,7 +1312,7 @@ std::chrono::steady_clock::duration MGLDurationInSeconds(float duration)
else if (quickZoom.state == UIGestureRecognizerStateEnded || quickZoom.state == UIGestureRecognizerStateCancelled)
{
[self notifyGestureDidEndWithDrift:NO];
- [self unrotateIfNeededAnimated:YES];
+ [self unrotateIfNeededForGesture];
}
}
@@ -1340,7 +1342,7 @@ std::chrono::steady_clock::duration MGLDurationInSeconds(float duration)
else if (twoFingerDrag.state == UIGestureRecognizerStateEnded || twoFingerDrag.state == UIGestureRecognizerStateCancelled)
{
[self notifyGestureDidEndWithDrift:NO];
- [self unrotateIfNeededAnimated:YES];
+ [self unrotateIfNeededForGesture];
}
}
@@ -1648,8 +1650,6 @@ std::chrono::steady_clock::duration MGLDurationInSeconds(float duration)
};
}
_mbglMap->easeTo(cameraOptions, animationOptions);
-
- [self unrotateIfNeededAnimated:animated];
}
+ (NS_SET_OF(NSString *) *)keyPathsForValuesAffectingZoomLevel
@@ -1766,8 +1766,6 @@ std::chrono::steady_clock::duration MGLDurationInSeconds(float duration)
}
_mbglMap->easeTo(cameraOptions, animationOptions);
[self didChangeValueForKey:@"visibleCoordinateBounds"];
-
- [self unrotateIfNeededAnimated:duration > 0];
}
+ (NS_SET_OF(NSString *) *)keyPathsForValuesAffectingDirection
@@ -3004,6 +3002,7 @@ std::chrono::steady_clock::duration MGLDurationInSeconds(float duration)
// at sufficient detail, just re-center the map; don't zoom
//
[self _setCenterCoordinate:self.userLocation.location.coordinate zoomLevel:self.zoomLevel direction:course animated:YES completionHandler:NULL];
+ [self unrotateIfNeededAnimated:YES];
}
else
{
@@ -3034,6 +3033,7 @@ std::chrono::steady_clock::duration MGLDurationInSeconds(float duration)
{
// assumes we won't disrupt tracking mode
[self setVisibleCoordinateBounds:MGLCoordinateBoundsMake(desiredSouthWest, desiredNorthEast) edgePadding:UIEdgeInsetsZero direction:course animated:YES];
+ [self unrotateIfNeededAnimated:YES];
}
}
}
@@ -3139,18 +3139,30 @@ std::chrono::steady_clock::duration MGLDurationInSeconds(float duration)
return (self.zoomLevel >= self.currentMinimumZoom);
}
-// correct rotations to north as needed
-//
-- (void)unrotateIfNeededAnimated:(BOOL)animated
+- (void)unrotateIfNeededForGesture
{
- double snapTolerance = 7;
-
- // don't worry about it in the midst of pinch or rotate gestures
- //
- if (self.pinch.state == UIGestureRecognizerStateChanged || self.rotate.state == UIGestureRecognizerStateChanged) return;
+ // Avoid contention with in-progress gestures.
+ UIGestureRecognizerState state = self.pinch.state;
+ if (self.direction != 0
+ && state != UIGestureRecognizerStateBegan
+ && state != UIGestureRecognizerStateChanged)
+ {
+ [self unrotateIfNeededAnimated:YES];
+
+ // Snap to north.
+ if ((self.direction < MGLToleranceForSnappingToNorth
+ || self.direction > 360 - MGLToleranceForSnappingToNorth)
+ && self.userTrackingMode != MGLUserTrackingModeFollowWithHeading
+ && self.userTrackingMode != MGLUserTrackingModeFollowWithCourse)
+ {
+ [self resetNorthAnimated:YES];
+ }
+ }
+}
- // but otherwise, do
- //
+/// Rotate back to true north if the map view is zoomed too far out.
+- (void)unrotateIfNeededAnimated:(BOOL)animated
+{
if (self.direction != 0 && ! self.isRotationAllowed)
{
if (animated)
@@ -3175,12 +3187,6 @@ std::chrono::steady_clock::duration MGLDurationInSeconds(float duration)
[self resetNorthAnimated:NO];
}
}
- else if ((self.direction < snapTolerance || self.direction > 360 - snapTolerance)
- && self.userTrackingMode != MGLUserTrackingModeFollowWithHeading
- && self.userTrackingMode != MGLUserTrackingModeFollowWithCourse)
- {
- [self resetNorthAnimated:animated];
- }
}
- (void)notifyMapChange:(mbgl::MapChange)change