summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMinh Nguyễn <mxn@1ec5.org>2016-06-29 15:48:02 -0700
committerGitHub <noreply@github.com>2016-06-29 15:48:02 -0700
commit5389f04da5f66c5e26d71e761a0fcda4d8382581 (patch)
tree3fb0d65b0d54d31f0569b6ad4aa3b8d8b351ad61
parentf7b646cac59e1a31157a8eebae595b613d548971 (diff)
downloadqtlocation-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.
-rw-r--r--platform/ios/CHANGELOG.md1
-rw-r--r--platform/ios/jazzy.yml3
-rw-r--r--platform/ios/src/MGLMapView.h20
-rw-r--r--platform/ios/src/MGLMapView.mm30
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];
}];