diff options
author | Minh Nguyễn <mxn@1ec5.org> | 2016-06-29 15:48:02 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2016-06-29 15:48:02 -0700 |
commit | 5389f04da5f66c5e26d71e761a0fcda4d8382581 (patch) | |
tree | 3fb0d65b0d54d31f0569b6ad4aa3b8d8b351ad61 /platform | |
parent | f7b646cac59e1a31157a8eebae595b613d548971 (diff) | |
download | qtlocation-mapboxgl-5389f04da5f66c5e26d71e761a0fcda4d8382581.tar.gz |
Adjustable map deceleration rate (#5504)
* [ios] Adds the ability to customize map deceleration speed
* [ios] Made pinch, rotation deceleration adjustable too
Drift zooming and drift rotation also respect the deceleration rate. A side effect of this change is that drift zooming will come to a stop ever-so-slightly sooner now.
* [ios] Documented deceleration rates
Added documentation for deceleration rate constants. Also updated the changelog.
Diffstat (limited to 'platform')
-rw-r--r-- | platform/ios/CHANGELOG.md | 1 | ||||
-rw-r--r-- | platform/ios/jazzy.yml | 3 | ||||
-rw-r--r-- | platform/ios/src/MGLMapView.h | 20 | ||||
-rw-r--r-- | platform/ios/src/MGLMapView.mm | 30 |
4 files changed, 41 insertions, 13 deletions
diff --git a/platform/ios/CHANGELOG.md b/platform/ios/CHANGELOG.md index 4f1d1b7374..03f08104e3 100644 --- a/platform/ios/CHANGELOG.md +++ b/platform/ios/CHANGELOG.md @@ -15,6 +15,7 @@ Mapbox welcomes participation and contributions from everyone. Please read [CON - `MGLOfflinePackProgress` now indicates how many tiles have been downloaded and how much space they take up. ([#4874](https://github.com/mapbox/mapbox-gl-native/pull/4874)) - The compass, user dot, and visible annotations are now accessible to VoiceOver users. ([#1496](https://github.com/mapbox/mapbox-gl-native/pull/1496)) - Added a method to MGLMapView, `-anchorPointForGesture:`, that you can override to anchor gestures at a point other than the user location. ([#5302](https://github.com/mapbox/mapbox-gl-native/pull/5302)) +- Added a property to MGLMapView, `decelerationRate`, that allows you to speed up or slow down the drift animation at the end of a user gesture. You can also use this property to disable the drift animation entirely. ([#5504](https://github.com/mapbox/mapbox-gl-native/pull/5504)) - Fixed an issue (speculatively) where the tile cache could be included in iCloud backups. ([#5124](https://github.com/mapbox/mapbox-gl-native/pull/5124)) - Improved performance viewing regions with large landcover polygons when viewing a style that uses the Mapbox Streets source. ([#2444](https://github.com/mapbox/mapbox-gl-native/pull/2444)) - Fixed a memory leak when using raster resources. ([#5141](https://github.com/mapbox/mapbox-gl-native/pull/5141)) diff --git a/platform/ios/jazzy.yml b/platform/ios/jazzy.yml index 67d877cda3..fee1dd889b 100644 --- a/platform/ios/jazzy.yml +++ b/platform/ios/jazzy.yml @@ -21,6 +21,9 @@ custom_categories: - MGLMapCamera - MGLMapDebugMaskOptions - MGLMapView + - MGLMapViewDecelerationRateFast + - MGLMapViewDecelerationRateImmediate + - MGLMapViewDecelerationRateNormal - MGLMapViewDelegate - MGLStyle - MGLStyleDefaultVersion diff --git a/platform/ios/src/MGLMapView.h b/platform/ios/src/MGLMapView.h index 3f649e45d2..de851bc1e5 100644 --- a/platform/ios/src/MGLMapView.h +++ b/platform/ios/src/MGLMapView.h @@ -21,6 +21,15 @@ NS_ASSUME_NONNULL_BEGIN @protocol MGLCalloutView; @protocol MGLFeature; +/** The default deceleration rate for a map view. */ +extern const CGFloat MGLMapViewDecelerationRateNormal; + +/** A fast deceleration rate for a map view. */ +extern const CGFloat MGLMapViewDecelerationRateFast; + +/** Disables decleration in a map view. */ +extern const CGFloat MGLMapViewDecelerationRateImmediate; + /** The vertical alignment of an annotation within a map view. */ typedef NS_ENUM(NSUInteger, MGLAnnotationVerticalAlignment) { /** Aligns the annotation vertically in the center of the map view. */ @@ -404,6 +413,17 @@ IB_DESIGNABLE */ @property(nonatomic, getter=isPitchEnabled) BOOL pitchEnabled; +/** + A floating-point value that determines the rate of deceleration after the user + lifts their finger. + + Your application can use the `MGLMapViewDecelerationRateNormal` and + `MGLMapViewDecelerationRateFast` constants as reference points for reasonable + deceleration rates. `MGLMapViewDecelerationRateImmediate` can be used to + disable deceleration entirely. + */ +@property(nonatomic) CGFloat decelerationRate; + #pragma mark Manipulating the Viewpoint /** diff --git a/platform/ios/src/MGLMapView.mm b/platform/ios/src/MGLMapView.mm index 23aa9a2a1b..78ee518d29 100644 --- a/platform/ios/src/MGLMapView.mm +++ b/platform/ios/src/MGLMapView.mm @@ -51,6 +51,10 @@ class MBGLView; class MGLAnnotationContext; +const CGFloat MGLMapViewDecelerationRateNormal = UIScrollViewDecelerationRateNormal; +const CGFloat MGLMapViewDecelerationRateFast = UIScrollViewDecelerationRateFast; +const CGFloat MGLMapViewDecelerationRateImmediate = 0.0; + /// Indicates the manner in which the map view is tracking the user location. typedef NS_ENUM(NSUInteger, MGLUserTrackingState) { /// The map view is not yet tracking the user location. @@ -500,6 +504,8 @@ mbgl::Duration MGLDurationInSeconds(NSTimeInterval duration) [self addGestureRecognizer:_twoFingerDrag]; _pitchEnabled = YES; + _decelerationRate = MGLMapViewDecelerationRateNormal; + if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) { _quickZoom = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(handleQuickZoomGesture:)]; @@ -1202,18 +1208,17 @@ mbgl::Duration MGLDurationInSeconds(NSTimeInterval duration) else if (pan.state == UIGestureRecognizerStateEnded || pan.state == UIGestureRecognizerStateCancelled) { CGPoint velocity = [pan velocityInView:pan.view]; - if (sqrtf(velocity.x * velocity.x + velocity.y * velocity.y) < 100) + if (self.decelerationRate == MGLMapViewDecelerationRateImmediate || sqrtf(velocity.x * velocity.x + velocity.y * velocity.y) < 100) { // Not enough velocity to overcome friction velocity = CGPointZero; } - NSTimeInterval duration = UIScrollViewDecelerationRateNormal; BOOL drift = ! CGPointEqualToPoint(velocity, CGPointZero); if (drift) { - CGPoint offset = CGPointMake(velocity.x * duration / 4, velocity.y * duration / 4); - _mbglMap->moveBy({ offset.x, offset.y }, MGLDurationInSeconds(duration)); + CGPoint offset = CGPointMake(velocity.x * self.decelerationRate / 4, velocity.y * self.decelerationRate / 4); + _mbglMap->moveBy({ offset.x, offset.y }, MGLDurationInSeconds(self.decelerationRate)); } [self notifyGestureDidEndWithDrift:drift]; @@ -1283,7 +1288,7 @@ mbgl::Duration MGLDurationInSeconds(NSTimeInterval duration) velocity = 0; } - NSTimeInterval duration = velocity > 0 ? 1 : 0.25; + NSTimeInterval duration = (velocity > 0 ? 1 : 0.25) * self.decelerationRate; CGFloat scale = self.scale * pinch.scale; CGFloat newScale = scale; @@ -1301,12 +1306,12 @@ mbgl::Duration MGLDurationInSeconds(NSTimeInterval duration) velocity = 0; } - if (velocity) + if (velocity && duration) { _mbglMap->setScale(newScale, mbgl::ScreenCoordinate { centerPoint.x, centerPoint.y }, MGLDurationInSeconds(duration)); } - [self notifyGestureDidEndWithDrift:velocity]; + [self notifyGestureDidEndWithDrift:velocity && duration]; [self unrotateIfNeededForGesture]; } @@ -1355,21 +1360,20 @@ mbgl::Duration MGLDurationInSeconds(NSTimeInterval duration) else if (rotate.state == UIGestureRecognizerStateEnded || rotate.state == UIGestureRecognizerStateCancelled) { CGFloat velocity = rotate.velocity; - - if (fabs(velocity) > 3) + CGFloat decelerationRate = self.decelerationRate; + if (decelerationRate != MGLMapViewDecelerationRateImmediate && fabs(velocity) > 3) { CGFloat radians = self.angle + rotate.rotation; - NSTimeInterval duration = UIScrollViewDecelerationRateNormal; - CGFloat newRadians = radians + velocity * duration * 0.1; + CGFloat newRadians = radians + velocity * decelerationRate * 0.1; CGFloat newDegrees = MGLDegreesFromRadians(newRadians) * -1; - _mbglMap->setBearing(newDegrees, mbgl::ScreenCoordinate { centerPoint.x, centerPoint.y }, MGLDurationInSeconds(duration)); + _mbglMap->setBearing(newDegrees, mbgl::ScreenCoordinate { centerPoint.x, centerPoint.y }, MGLDurationInSeconds(decelerationRate)); [self notifyGestureDidEndWithDrift:YES]; __weak MGLMapView *weakSelf = self; - [self animateWithDelay:duration animations:^ + [self animateWithDelay:decelerationRate animations:^ { [weakSelf unrotateIfNeededForGesture]; }]; |