diff options
author | jmkiley <jordan.kiley@mapbox.com> | 2019-08-20 15:31:15 -0700 |
---|---|---|
committer | jmkiley <jordan.kiley@mapbox.com> | 2019-08-20 15:31:15 -0700 |
commit | d0b2052514745f17d9df3fdc6f5eac9f88f55a51 (patch) | |
tree | 69b5c9999886f70ee122e080cbc420eb29a9ed2b | |
parent | f4746d02e1bf146c662752752b410333b222ea6c (diff) | |
download | qtlocation-mapboxgl-d0b2052514745f17d9df3fdc6f5eac9f88f55a51.tar.gz |
[ios] Move code into a check
-rw-r--r-- | platform/ios/src/MGLMapView.mm | 116 |
1 files changed, 101 insertions, 15 deletions
diff --git a/platform/ios/src/MGLMapView.mm b/platform/ios/src/MGLMapView.mm index ce882c4f5c..be2c3f2005 100644 --- a/platform/ios/src/MGLMapView.mm +++ b/platform/ios/src/MGLMapView.mm @@ -129,7 +129,7 @@ const CLLocationDirection MGLToleranceForSnappingToNorth = 7; const CLLocationDistance MGLDistanceThresholdForCameraPause = 500; /// Rotation threshold while a pinch gesture is occurring. -static NSString * const MGLRotationThresholdWhileZooming = @"MGLRotationThresholdWhileZooming"; +static NSString * const MGLRotationThresholdWhileZoomingKey = @"MGLRotationThresholdWhileZooming"; /// Reuse identifier and file name of the default point annotation image. static NSString * const MGLDefaultStyleMarkerSymbolName = @"default_marker"; @@ -577,13 +577,6 @@ public: [self addGestureRecognizer:_rotate]; _rotateEnabled = YES; - NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; - if ([defaults objectForKey:MGLRotationThresholdWhileZooming]) { - _rotationThresholdWhileZooming = [[defaults objectForKey:MGLRotationThresholdWhileZooming] floatValue]; - } else { - _rotationThresholdWhileZooming = 0; - } - _doubleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleDoubleTapGesture:)]; _doubleTap.numberOfTapsRequired = 2; [self addGestureRecognizer:_doubleTap]; @@ -1734,6 +1727,99 @@ public: self.cameraChangeReasonBitmask |= MGLCameraChangeReasonGestureRotate; + if ([[NSUserDefaults standardUserDefaults] objectForKey:MGLRotationThresholdWhileZoomingKey]) { + [self handleRotateGestureRecognizerWithThreshold:rotate]; + } else { + if (rotate.state == UIGestureRecognizerStateBegan) + { + self.angle = MGLRadiansFromDegrees(*self.mbglMap.getCameraOptions().bearing) * -1; + + self.isRotating = YES; + if (self.userTrackingMode != MGLUserTrackingModeNone) + { + self.userTrackingMode = MGLUserTrackingModeFollow; + } + + self.shouldTriggerHapticFeedbackForCompass = NO; + [self notifyGestureDidBegin]; + } + if (rotate.state == UIGestureRecognizerStateChanged) + { + CGFloat newDegrees = MGLDegreesFromRadians(self.angle + rotate.rotation) * -1; + + // constrain to +/-30 degrees when merely rotating like Apple does + // + if ( ! self.isRotationAllowed && std::abs(self.pinch.scale) < 10) + { + newDegrees = fminf(newDegrees, 30); + newDegrees = fmaxf(newDegrees, -30); + } + + MGLMapCamera *toCamera = [self cameraByRotatingToDirection:newDegrees aroundAnchorPoint:centerPoint]; + + if ([self _shouldChangeFromCamera:oldCamera toCamera:toCamera]) + { + self.mbglMap.jumpTo(mbgl::CameraOptions() + .withBearing(newDegrees) + .withAnchor(mbgl::ScreenCoordinate { centerPoint.x, centerPoint.y})); + } + + [self cameraIsChanging]; + + // Trigger a light haptic feedback event when the user rotates to due north. + if (@available(iOS 10.0, *)) + { + if (self.isHapticFeedbackEnabled && fabs(newDegrees) <= 1 && self.shouldTriggerHapticFeedbackForCompass) + { + UIImpactFeedbackGenerator *hapticFeedback = [[UIImpactFeedbackGenerator alloc] initWithStyle:UIImpactFeedbackStyleLight]; + [hapticFeedback impactOccurred]; + + self.shouldTriggerHapticFeedbackForCompass = NO; + } + else if (fabs(newDegrees) > 1) + { + self.shouldTriggerHapticFeedbackForCompass = YES; + } + } + } + else if ((rotate.state == UIGestureRecognizerStateEnded || rotate.state == UIGestureRecognizerStateCancelled)) + { + CGFloat velocity = rotate.velocity; + CGFloat decelerationRate = self.decelerationRate; + if (decelerationRate != MGLMapViewDecelerationRateImmediate && fabs(velocity) > 3) + { + CGFloat radians = self.angle + rotate.rotation; + CGFloat newRadians = radians + velocity * decelerationRate * 0.1; + CGFloat newDegrees = MGLDegreesFromRadians(newRadians) * -1; + + MGLMapCamera *toCamera = [self cameraByRotatingToDirection:newDegrees aroundAnchorPoint:centerPoint]; + + if ([self _shouldChangeFromCamera:oldCamera toCamera:toCamera]) + { + self.mbglMap.easeTo(mbgl::CameraOptions() + .withBearing(newDegrees) + .withAnchor(mbgl::ScreenCoordinate { centerPoint.x, centerPoint.y }), + MGLDurationFromTimeInterval(decelerationRate)); + + [self notifyGestureDidEndWithDrift:YES]; + __weak MGLMapView *weakSelf = self; + + [self animateWithDelay:decelerationRate animations:^ + { + [weakSelf unrotateIfNeededForGesture]; + }]; + } + } + else + { + [self notifyGestureDidEndWithDrift:NO]; + [self unrotateIfNeededForGesture]; + } + } + } +} + +- (void)handleRotateGestureRecognizerWithThreshold:(UIRotationGestureRecognizer *)rotate { // Check whether a zoom triggered by a pinch gesture is occurring and if the rotation threshold has been met. if (MGLDegreesFromRadians(self.rotationBeforeThresholdMet) < self.rotationThresholdWhileZooming && self.isZooming && !self.isRotating) { self.rotationBeforeThresholdMet += fabs(rotate.rotation); @@ -1765,14 +1851,14 @@ public: newDegrees = fminf(newDegrees, 30); newDegrees = fmaxf(newDegrees, -30); } - + MGLMapCamera *toCamera = [self cameraByRotatingToDirection:newDegrees aroundAnchorPoint:centerPoint]; if ([self _shouldChangeFromCamera:oldCamera toCamera:toCamera]) { - self.mbglMap.jumpTo(mbgl::CameraOptions() - .withBearing(newDegrees) - .withAnchor(mbgl::ScreenCoordinate { centerPoint.x, centerPoint.y})); + self.mbglMap.jumpTo(mbgl::CameraOptions() + .withBearing(newDegrees) + .withAnchor(mbgl::ScreenCoordinate { centerPoint.x, centerPoint.y})); } [self cameraIsChanging]; @@ -1812,13 +1898,13 @@ public: if ([self _shouldChangeFromCamera:oldCamera toCamera:toCamera]) { self.mbglMap.easeTo(mbgl::CameraOptions() - .withBearing(newDegrees) - .withAnchor(mbgl::ScreenCoordinate { centerPoint.x, centerPoint.y }), + .withBearing(newDegrees) + .withAnchor(mbgl::ScreenCoordinate { centerPoint.x, centerPoint.y }), MGLDurationFromTimeInterval(decelerationRate)); [self notifyGestureDidEndWithDrift:YES]; __weak MGLMapView *weakSelf = self; - + [self animateWithDelay:decelerationRate animations:^ { [weakSelf unrotateIfNeededForGesture]; |