summaryrefslogtreecommitdiff
path: root/platform/ios/src
diff options
context:
space:
mode:
authorJulian Rex <julian.rex@mapbox.com>2018-02-12 11:36:03 -0500
committerJulian Rex <julian.rex@mapbox.com>2018-02-12 11:36:03 -0500
commit99582b773ebe1b0e39240fc608135a1742b4fa73 (patch)
treeedf3b4f5a2f440696c5b8dcee440ea8991b9a862 /platform/ios/src
parent0faad452a96ce6644cfc4ac07ec0e0c76e136935 (diff)
downloadqtlocation-mapboxgl-upstream/jrex-10674-enum.tar.gz
[ios] Made reason bitmask private, created public enum, and provided a mapping from the bitmask to enumupstream/jrex-10674-enum
Diffstat (limited to 'platform/ios/src')
-rw-r--r--platform/ios/src/MGLCameraChange.h35
-rw-r--r--platform/ios/src/MGLCameraChangeReason.h54
-rw-r--r--platform/ios/src/MGLCameraChangeReason_Private.h42
-rw-r--r--platform/ios/src/MGLMapView.mm99
-rw-r--r--platform/ios/src/MGLMapViewDelegate.h2
5 files changed, 177 insertions, 55 deletions
diff --git a/platform/ios/src/MGLCameraChange.h b/platform/ios/src/MGLCameraChange.h
deleted file mode 100644
index c2f7728f2c..0000000000
--- a/platform/ios/src/MGLCameraChange.h
+++ /dev/null
@@ -1,35 +0,0 @@
-#import "MGLFoundation.h"
-
-typedef NS_OPTIONS(NSUInteger, MGLCameraChangeReason)
-{
- /// No reason for the camera move is specified.
- MGLCameraChangeReasonNone = 0,
-
- /// Set when a public API that moves the camera is called. This may be set for some gestures
- MGLCameraChangeReasonProgrammatic = 1 << 0,
-
- /// User tapped the compass to reset to North
- MGLCameraChangeReasonResetNorth = 1 << 1,// Tap on compass
-
- /// User panned the map.
- MGLCameraChangeReasonGesturePan = 1 << 2,
-
- /// User pinched to zoom in/out
- MGLCameraChangeReasonGesturePinch = 1 << 3,
-
- // User rotated the map
- MGLCameraChangeReasonGestureRotate = 1 << 4,
-
- /// User zoomed the map in
- MGLCameraChangeReasonGestureZoomIn = 1 << 5,// One finger double tap
-
- /// User zoomed the map out
- MGLCameraChangeReasonGestureZoomOut = 1 << 6,// Two finger single tap
-
- /// User long pressed on the map for a quick zoom
- MGLCameraChangeReasonGestureQuickZoom = 1 << 7,// Long press
-
- // User panned with two fingers to tilt the map
- MGLCameraChangeReasonGesturePitch = 1 << 8// Two finger drag
-};
-
diff --git a/platform/ios/src/MGLCameraChangeReason.h b/platform/ios/src/MGLCameraChangeReason.h
new file mode 100644
index 0000000000..5fb990afdd
--- /dev/null
+++ b/platform/ios/src/MGLCameraChangeReason.h
@@ -0,0 +1,54 @@
+#import "MGLFoundation.h"
+
+/**
+ Reasons describing why a camera move occurred.
+
+ Values of this type are passed to the `MGLMapView`'s delegate in the following methods:
+
+ - `-mapView:shouldChangeFromCamera:toCamera:reason:`
+ - `-mapView:regionWillChangeWithReason:animated:`
+ - `-mapView:regionIsChangingWithReason:`
+ - `-mapView:regionDidChangeWithReason:animated:`
+
+ It's important to note that it's almost impossible to perform a rotate without zooming (in or out),
+ so when you want to check for a pan vs a rotation, it's important to ensure you check
+ MGLCameraChangeReasonGesturePan against MGLCameraChangeReasonGestureRotateAndZoom.
+*/
+typedef NS_ENUM(NSUInteger, MGLCameraChangeReason)
+{
+ /// The reason for the camera change is invalid. This is considered an error.
+ MGLCameraChangeReasonInvalid,
+
+ /// Set when a public API that moves the camera is called.
+ MGLCameraChangeReasonProgrammatic,
+
+ /// The user panned the map.
+ MGLCameraChangeReasonGesturePan,
+
+ /// The user rotated the map. This is also used when the user resets the map orientation by tapping
+ /// on the compass. Note that since it's almost impossible to rotate without zooming, you should
+ /// also check against MGLCameraChangeReasonGestureRotateAndZoom
+ MGLCameraChangeReasonGestureRotate,
+
+ /// The user zoomed the map. This is used when pinching the map, double tapping and for the one
+ /// finger drag zoom gesture.
+ MGLCameraChangeReasonGestureZoom,
+
+ /// The user panned and rotated the map, without lifting their fingers.
+ MGLCameraChangeReasonGesturePanAndRotate,
+
+ /// The user rotated and zoomed the map. You will see this value when rotating the map without a
+ /// deliberate zoom. See also MGLCameraChangeReasonGestureRotate.
+ MGLCameraChangeReasonGestureRotateAndZoom,
+
+ /// The user panned and zoomed the map, without lifting their fingers.
+ MGLCameraChangeReasonGesturePanAndZoom,
+
+ /// The user panned, rotated and zoomed the map, without lifting their fingers.
+ MGLCameraChangeReasonGesturePanRotateAndZoom,
+
+ /// The user dragged the map with two fingers to tilt the map.
+ MGLCameraChangeReasonGestureTilt
+};
+
+
diff --git a/platform/ios/src/MGLCameraChangeReason_Private.h b/platform/ios/src/MGLCameraChangeReason_Private.h
new file mode 100644
index 0000000000..4c058b1d61
--- /dev/null
+++ b/platform/ios/src/MGLCameraChangeReason_Private.h
@@ -0,0 +1,42 @@
+#import "MGLFoundation.h"
+
+/**
+ Internal bitmask values used to represent ongoing gestures and API calls that triggers a camera
+ change.
+
+ At the end of a camera movement, the resulting bitmask is mapped to one of the public
+ MGLCameraChangeReason enum values and passed to the delegate camera change methods.
+ */
+typedef NS_OPTIONS(NSUInteger, MGLCameraChangeReasonBitmask)
+{
+ /// The default value. Set at the start, and reset when a camera move has completed.
+ MGLCameraChangeReasonBitmaskNone = 0,
+
+ /// Set when a public API that moves the camera is called. This may be set for some gestures,
+ /// for example, when the user taps the compass to reset north.
+ MGLCameraChangeReasonBitmaskProgrammatic = 1 << 0,
+
+ /// The user tapped the compass to reset the map orientation so North is up.
+ MGLCameraChangeReasonBitmaskResetNorth = 1 << 1,
+
+ /// The user panned the map.
+ MGLCameraChangeReasonBitmaskGesturePan = 1 << 2,
+
+ /// The user pinched to zoom in/out.
+ MGLCameraChangeReasonBitmaskGesturePinch = 1 << 3,
+
+ /// The user rotated the map.
+ MGLCameraChangeReasonBitmaskGestureRotate = 1 << 4,
+
+ /// The user zoomed the map in. (One finger double tap.)
+ MGLCameraChangeReasonBitmaskGestureZoomIn = 1 << 5,
+
+ /// The user zoomed the map out. (Two finger single tap.)
+ MGLCameraChangeReasonBitmaskGestureZoomOut = 1 << 6,
+
+ /// The user long pressed on the map for a quick zoom. (Single tap, then long press and drag up/down.)
+ MGLCameraChangeReasonBitmaskGestureOneFingerZoom = 1 << 7,
+
+ // The user panned with two fingers to tilt the map. (Two finger drag.)
+ MGLCameraChangeReasonBitmaskGestureTwoFingerDrag = 1 << 8
+};
diff --git a/platform/ios/src/MGLMapView.mm b/platform/ios/src/MGLMapView.mm
index d2496d8627..90a67840fe 100644
--- a/platform/ios/src/MGLMapView.mm
+++ b/platform/ios/src/MGLMapView.mm
@@ -41,6 +41,8 @@
#import "MGLMultiPoint_Private.h"
#import "MGLOfflineStorage_Private.h"
#import "MGLFoundation_Private.h"
+#import "MGLCameraChangeReason_Private.h"
+
#import "MGLRendererFrontend.h"
#import "MGLRendererConfiguration.h"
@@ -209,7 +211,9 @@ public:
@property (nonatomic) UILongPressGestureRecognizer *quickZoom;
@property (nonatomic) UIPanGestureRecognizer *twoFingerDrag;
-@property (nonatomic) MGLCameraChangeReason cameraChangeReason;
+/// Camera change reason handling.
+@property (nonatomic) MGLCameraChangeReasonBitmask cameraChangeReasonBitmask;
+@property (nonatomic, readonly) MGLCameraChangeReason cameraChangeReason;
/// Mapping from reusable identifiers to annotation images.
@property (nonatomic) NS_MUTABLE_DICTIONARY_OF(NSString *, MGLAnnotationImage *) *annotationImagesByIdentifier;
@@ -555,7 +559,7 @@ public:
options.padding = padding;
options.zoom = 0;
- _cameraChangeReason = MGLCameraChangeReasonNone;
+ _cameraChangeReasonBitmask = MGLCameraChangeReasonBitmaskNone;
_mbglMap->jumpTo(options);
_pendingLatitude = NAN;
@@ -1243,7 +1247,7 @@ public:
- (void)handleCompassTapGesture:(__unused id)sender
{
- self.cameraChangeReason |= MGLCameraChangeReasonResetNorth;
+ self.cameraChangeReasonBitmask |= MGLCameraChangeReasonBitmaskResetNorth;
[self resetNorthAnimated:YES];
@@ -1296,6 +1300,8 @@ public:
// Check delegates first
if ([self.delegate respondsToSelector:@selector(mapView:shouldChangeFromCamera:toCamera:reason:)])
{
+
+
return [self.delegate mapView:self shouldChangeFromCamera:oldCamera toCamera:newCamera reason:self.cameraChangeReason];
}
else if ([self.delegate respondsToSelector:@selector(mapView:shouldChangeFromCamera:toCamera:)])
@@ -1316,7 +1322,7 @@ public:
MGLMapCamera *oldCamera = self.camera;
- self.cameraChangeReason |= MGLCameraChangeReasonGesturePan;
+ self.cameraChangeReasonBitmask |= MGLCameraChangeReasonGesturePan;
if (pan.state == UIGestureRecognizerStateBegan)
{
@@ -1386,7 +1392,7 @@ public:
CGPoint centerPoint = [self anchorPointForGesture:pinch];
MGLMapCamera *oldCamera = self.camera;
- self.cameraChangeReason |= MGLCameraChangeReasonGesturePinch;
+ self.cameraChangeReasonBitmask |= MGLCameraChangeReasonBitmaskGesturePinch;
if (pinch.state == UIGestureRecognizerStateBegan)
{
@@ -1485,7 +1491,7 @@ public:
CGPoint centerPoint = [self anchorPointForGesture:rotate];
MGLMapCamera *oldCamera = self.camera;
- self.cameraChangeReason |= MGLCameraChangeReasonGestureRotate;
+ self.cameraChangeReasonBitmask |= MGLCameraChangeReasonGestureRotate;
if (rotate.state == UIGestureRecognizerStateBegan)
{
@@ -1671,7 +1677,7 @@ public:
if (doubleTap.state == UIGestureRecognizerStateEnded)
{
- self.cameraChangeReason |= MGLCameraChangeReasonGestureZoomIn;
+ self.cameraChangeReasonBitmask |= MGLCameraChangeReasonBitmaskGestureZoomIn;
MGLMapCamera *oldCamera = self.camera;
@@ -1708,7 +1714,7 @@ public:
_mbglMap->cancelTransitions();
- self.cameraChangeReason |= MGLCameraChangeReasonGestureZoomOut;
+ self.cameraChangeReasonBitmask |= MGLCameraChangeReasonBitmaskGestureZoomOut;
if (twoFingerTap.state == UIGestureRecognizerStateBegan)
{
@@ -1747,7 +1753,7 @@ public:
_mbglMap->cancelTransitions();
- self.cameraChangeReason |= MGLCameraChangeReasonGestureQuickZoom;
+ self.cameraChangeReasonBitmask |= MGLCameraChangeReasonBitmaskGestureOneFingerZoom;
if (quickZoom.state == UIGestureRecognizerStateBegan)
{
@@ -1792,7 +1798,7 @@ public:
_mbglMap->cancelTransitions();
- self.cameraChangeReason |= MGLCameraChangeReasonGesturePitch;
+ self.cameraChangeReasonBitmask |= MGLCameraChangeReasonBitmaskGestureTwoFingerDrag;
if (twoFingerDrag.state == UIGestureRecognizerStateBegan)
{
@@ -1980,6 +1986,7 @@ public:
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{
+ // If you update these, please check to see if `-cameraChangeReason` needs updating.
NSArray *validSimultaneousGestures = @[ self.pan, self.pinch, self.rotate ];
return ([validSimultaneousGestures containsObject:gestureRecognizer] && [validSimultaneousGestures containsObject:otherGestureRecognizer]);
@@ -2889,7 +2896,7 @@ public:
{
self.userTrackingMode = MGLUserTrackingModeNone;
- self.cameraChangeReason |= MGLCameraChangeReasonProgrammatic;
+ self.cameraChangeReasonBitmask |= MGLCameraChangeReasonBitmaskProgrammatic;
[self _setCenterCoordinate:centerCoordinate edgePadding:self.contentInset zoomLevel:zoomLevel direction:direction duration:animated ? MGLAnimationDuration : 0 animationTimingFunction:nil completionHandler:completion];
}
@@ -2941,7 +2948,7 @@ public:
_mbglMap->cancelTransitions();
- self.cameraChangeReason |= MGLCameraChangeReasonProgrammatic;
+ self.cameraChangeReasonBitmask |= MGLCameraChangeReasonBitmaskProgrammatic;
_mbglMap->easeTo(cameraOptions, animationOptions);
}
@@ -2966,7 +2973,7 @@ public:
if (zoomLevel == self.zoomLevel) return;
_mbglMap->cancelTransitions();
- self.cameraChangeReason |= MGLCameraChangeReasonProgrammatic;
+ self.cameraChangeReasonBitmask |= MGLCameraChangeReasonBitmaskProgrammatic;
CGFloat duration = animated ? MGLAnimationDuration : 0;
@@ -3057,7 +3064,7 @@ public:
{
self.userTrackingMode = MGLUserTrackingModeNone;
- self.cameraChangeReason |= MGLCameraChangeReasonProgrammatic;
+ self.cameraChangeReasonBitmask |= MGLCameraChangeReasonBitmaskProgrammatic;
[self _setVisibleCoordinates:coordinates count:count edgePadding:insets direction:direction duration:duration animationTimingFunction:function completionHandler:completion];
}
@@ -3109,7 +3116,7 @@ public:
[self willChangeValueForKey:@"visibleCoordinateBounds"];
_mbglMap->cancelTransitions();
- self.cameraChangeReason |= MGLCameraChangeReasonProgrammatic;
+ self.cameraChangeReasonBitmask |= MGLCameraChangeReasonBitmaskProgrammatic;
_mbglMap->easeTo(cameraOptions, animationOptions);
[self didChangeValueForKey:@"visibleCoordinateBounds"];
@@ -3144,7 +3151,7 @@ public:
CGFloat duration = animated ? MGLAnimationDuration : 0;
- self.cameraChangeReason |= MGLCameraChangeReasonProgrammatic;
+ self.cameraChangeReasonBitmask |= MGLCameraChangeReasonBitmaskProgrammatic;
if (self.userTrackingMode == MGLUserTrackingModeNone)
{
@@ -3231,7 +3238,7 @@ public:
[self willChangeValueForKey:@"camera"];
_mbglMap->cancelTransitions();
- self.cameraChangeReason |= MGLCameraChangeReasonProgrammatic;
+ self.cameraChangeReasonBitmask |= MGLCameraChangeReasonBitmaskProgrammatic;
mbgl::CameraOptions cameraOptions = [self cameraOptionsObjectForAnimatingToCamera:camera edgePadding:edgePadding];
_mbglMap->easeTo(cameraOptions, animationOptions);
@@ -3290,7 +3297,7 @@ public:
[self willChangeValueForKey:@"camera"];
_mbglMap->cancelTransitions();
- self.cameraChangeReason |= MGLCameraChangeReasonProgrammatic;
+ self.cameraChangeReasonBitmask |= MGLCameraChangeReasonBitmaskProgrammatic;
mbgl::CameraOptions cameraOptions = [self cameraOptionsObjectForAnimatingToCamera:camera edgePadding:insets];
_mbglMap->flyTo(cameraOptions, animationOptions);
@@ -3456,9 +3463,61 @@ public:
- (void)resetCameraChangeReason
{
- self.cameraChangeReason = MGLCameraChangeReasonNone;
+ self.cameraChangeReasonBitmask = MGLCameraChangeReasonBitmaskNone;
+}
+
+- (MGLCameraChangeReason)cameraChangeReason
+{
+ static NSDictionary *reasonMap = nil;
+
+ static dispatch_once_t onceToken;
+ dispatch_once(&onceToken, ^{
+ reasonMap =
+ @{
+ // Pan, Rotate and Pinch can all be recognized simultaneously
+ @(MGLCameraChangeReasonBitmaskGesturePan) : @(MGLCameraChangeReasonGesturePan),
+ @(MGLCameraChangeReasonBitmaskGestureRotate) : @(MGLCameraChangeReasonGestureRotate),
+ @(MGLCameraChangeReasonBitmaskGesturePinch) : @(MGLCameraChangeReasonGestureZoom),
+
+ @(MGLCameraChangeReasonBitmaskGesturePan|MGLCameraChangeReasonBitmaskGestureRotate) : @(MGLCameraChangeReasonGesturePanAndRotate),
+ @(MGLCameraChangeReasonBitmaskGesturePan|MGLCameraChangeReasonBitmaskGesturePinch) : @(MGLCameraChangeReasonGesturePanAndZoom),
+ @(MGLCameraChangeReasonBitmaskGestureRotate|MGLCameraChangeReasonBitmaskGesturePinch) : @(MGLCameraChangeReasonGestureRotateAndZoom),
+
+ @(MGLCameraChangeReasonBitmaskGesturePan|MGLCameraChangeReasonBitmaskGestureRotate|MGLCameraChangeReasonBitmaskGesturePinch) : @(MGLCameraChangeReasonGesturePanRotateAndZoom),
+
+ // Tilt
+ @(MGLCameraChangeReasonBitmaskGestureTwoFingerDrag) : @(MGLCameraChangeReasonGestureTilt),
+
+ // Custom gestures that can map to existing reasons
+ @(MGLCameraChangeReasonBitmaskResetNorth|MGLCameraChangeReasonBitmaskProgrammatic) : @(MGLCameraChangeReasonGestureRotate),
+ @(MGLCameraChangeReasonBitmaskGestureZoomIn) : @(MGLCameraChangeReasonGestureZoom),
+ @(MGLCameraChangeReasonBitmaskGestureZoomOut) : @(MGLCameraChangeReasonGestureZoom),
+ @(MGLCameraChangeReasonBitmaskGestureOneFingerZoom) : @(MGLCameraChangeReasonGestureZoom),
+ };
+ });
+
+ // For the end user we provide an enum for the change reason, so we need to map from our internal
+ // mask to this enum. We don't cover all possible combinations since only a subset of gestures
+ // can be recognized simultaneously. If you change -gestureRecognizer:shouldRecognizeSimultaneouslyWithGestureRecognizer:
+ // then please be sure to make sure this method is updated if necessary.
+
+ NSNumber *reason = reasonMap[@(self.cameraChangeReasonBitmask)];
+ if (reason)
+ {
+ return (MGLCameraChangeReason)[reason unsignedIntegerValue];
+ }
+ else if (self.cameraChangeReasonBitmask & MGLCameraChangeReasonBitmaskProgrammatic)
+ {
+ return MGLCameraChangeReasonProgrammatic;
+ }
+ else
+ {
+ NSAssert(0, @"Camera change reason: %ld missing from mapping table.", self.cameraChangeReasonBitmask);
+ return MGLCameraChangeReasonInvalid;
+ }
}
+
#pragma mark - Styling -
- (NS_ARRAY_OF(NSURL *) *)bundledStyleURLs
@@ -5467,6 +5526,8 @@ public:
if (respondsToSelectorWithReason)
{
+
+
[self.delegate mapView:self regionDidChangeWithReason:self.cameraChangeReason animated:animated];
}
else if (respondsToSelector)
diff --git a/platform/ios/src/MGLMapViewDelegate.h b/platform/ios/src/MGLMapViewDelegate.h
index abb2e9be03..eca01853ff 100644
--- a/platform/ios/src/MGLMapViewDelegate.h
+++ b/platform/ios/src/MGLMapViewDelegate.h
@@ -1,7 +1,7 @@
#import <UIKit/UIKit.h>
#import "MGLTypes.h"
-#import "MGLCameraChange.h"
+#import "MGLCameraChangeReason.h"
NS_ASSUME_NONNULL_BEGIN