summaryrefslogtreecommitdiff
path: root/platform/ios/src/MGLAnnotationView.mm
diff options
context:
space:
mode:
authorFredrik Karlsson <bjorn.fredrik.karlsson@gmail.com>2016-06-24 19:42:20 +0200
committerGitHub <noreply@github.com>2016-06-24 19:42:20 +0200
commitd29bef957fe117158077a5af223d3cee14032ee2 (patch)
treec6f975fbf0bc4bf224643813a5e4117049704b1f /platform/ios/src/MGLAnnotationView.mm
parent05b6e724935277920a2c5f8282993b50d26f9719 (diff)
downloadqtlocation-mapboxgl-d29bef957fe117158077a5af223d3cee14032ee2.tar.gz
[ios] fixes #5036 draggable annotation views (#5373)
Diffstat (limited to 'platform/ios/src/MGLAnnotationView.mm')
-rw-r--r--platform/ios/src/MGLAnnotationView.mm136
1 files changed, 134 insertions, 2 deletions
diff --git a/platform/ios/src/MGLAnnotationView.mm b/platform/ios/src/MGLAnnotationView.mm
index 04a888f5e6..e086e3bde5 100644
--- a/platform/ios/src/MGLAnnotationView.mm
+++ b/platform/ios/src/MGLAnnotationView.mm
@@ -1,15 +1,19 @@
#import "MGLAnnotationView.h"
#import "MGLAnnotationView_Private.h"
+#import "MGLAnnotation.h"
#import "MGLMapView_Internal.h"
#import "NSBundle+MGLAdditions.h"
#include <mbgl/util/constants.hpp>
-@interface MGLAnnotationView ()
+@interface MGLAnnotationView () <UIGestureRecognizerDelegate>
@property (nonatomic, readwrite, nullable) NSString *reuseIdentifier;
@property (nonatomic, readwrite, nullable) id <MGLAnnotation> annotation;
+@property (nonatomic, weak) UIPanGestureRecognizer *panGestureRecognizer;
+@property (nonatomic, weak) UILongPressGestureRecognizer *longPressRecognizer;
+@property (nonatomic, weak) MGLMapView *mapView;
@end
@@ -62,6 +66,11 @@
[super setCenter:center];
+ // Omit applying a new transformation while the view is being dragged.
+ if (self.dragState == MGLAnnotationViewDragStateDragging) {
+ return;
+ }
+
if (self.flat)
{
[self updatePitch:pitch];
@@ -108,6 +117,129 @@
}
}
+#pragma mark - Draggable
+
+- (void)setDraggable:(BOOL)draggable
+{
+ [self willChangeValueForKey:@"draggable"];
+ _draggable = draggable;
+ [self didChangeValueForKey:@"draggable"];
+
+ if (draggable)
+ {
+ [self enableDrag];
+ }
+ else
+ {
+ [self disableDrag];
+ }
+}
+
+- (void)enableDrag
+{
+ if (!_longPressRecognizer)
+ {
+ UILongPressGestureRecognizer *recognizer = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(handleLongPress:)];
+ recognizer.delegate = self;
+ [self addGestureRecognizer:recognizer];
+ _longPressRecognizer = recognizer;
+ }
+
+ if (!_panGestureRecognizer)
+ {
+ UIPanGestureRecognizer *recognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handlePan:)];
+ recognizer.delegate = self;
+ [self addGestureRecognizer:recognizer];
+ _panGestureRecognizer = recognizer;
+ }
+}
+
+- (void)disableDrag
+{
+ [self removeGestureRecognizer:_longPressRecognizer];
+ [self removeGestureRecognizer:_panGestureRecognizer];
+}
+
+- (void)handleLongPress:(UILongPressGestureRecognizer *)sender
+{
+ switch (sender.state) {
+ case UIGestureRecognizerStateBegan:
+ self.dragState = MGLAnnotationViewDragStateStarting;
+ break;
+ case UIGestureRecognizerStateChanged:
+ self.dragState = MGLAnnotationViewDragStateDragging;
+ break;
+ case UIGestureRecognizerStateCancelled:
+ self.dragState = MGLAnnotationViewDragStateCanceling;
+ break;
+ case UIGestureRecognizerStateEnded:
+ self.dragState = MGLAnnotationViewDragStateEnding;
+ break;
+ case UIGestureRecognizerStateFailed:
+ self.dragState = MGLAnnotationViewDragStateNone;
+ break;
+ case UIGestureRecognizerStatePossible:
+ break;
+ }
+}
+
+- (void)handlePan:(UIPanGestureRecognizer *)sender
+{
+ CGPoint center = [sender locationInView:sender.view.superview];
+ [self setCenter:center pitch:self.mapView.camera.pitch];
+
+ if (sender.state == UIGestureRecognizerStateEnded) {
+ self.dragState = MGLAnnotationViewDragStateNone;
+ }
+}
+
+- (void)setDragState:(MGLAnnotationViewDragState)dragState
+{
+ [self setDragState:dragState animated:YES];
+}
+
+- (void)setDragState:(MGLAnnotationViewDragState)dragState animated:(BOOL)animated
+{
+ [self willChangeValueForKey:@"dragState"];
+ _dragState = dragState;
+ [self didChangeValueForKey:@"dragState"];
+
+ if (dragState == MGLAnnotationViewDragStateStarting)
+ {
+ [self.superview bringSubviewToFront:self];
+ }
+
+ if (dragState == MGLAnnotationViewDragStateEnding)
+ {
+ if ([self.mapView.delegate respondsToSelector:@selector(mapView:didDragAnnotationView:toCoordinate:)])
+ {
+ CGPoint offsetAdjustedCenter = self.center;
+ offsetAdjustedCenter.x -= self.centerOffset.dx;
+ offsetAdjustedCenter.y -= self.centerOffset.dy;
+
+ CLLocationCoordinate2D coordinate = [self.mapView convertPoint:offsetAdjustedCenter toCoordinateFromView:self.mapView];
+ [self.mapView.delegate mapView:self.mapView didDragAnnotationView:self toCoordinate:coordinate];
+ }
+ }
+}
+
+- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer
+{
+ BOOL isDragging = self.dragState == MGLAnnotationViewDragStateDragging;
+
+ if ([gestureRecognizer isKindOfClass:UIPanGestureRecognizer.class] && !(isDragging))
+ {
+ return NO;
+ }
+
+ return YES;
+}
+
+- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
+{
+ return YES;
+}
+
- (id<CAAction>)actionForLayer:(CALayer *)layer forKey:(NSString *)event
{
// Allow mbgl to drive animation of this view’s bounds.
@@ -157,4 +289,4 @@
[self.superview accessibilityDecrement];
}
-@end \ No newline at end of file
+@end