diff options
author | Fredrik Karlsson <bjorn.fredrik.karlsson@gmail.com> | 2016-06-24 19:42:20 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2016-06-24 19:42:20 +0200 |
commit | d29bef957fe117158077a5af223d3cee14032ee2 (patch) | |
tree | c6f975fbf0bc4bf224643813a5e4117049704b1f /platform/ios/src/MGLAnnotationView.mm | |
parent | 05b6e724935277920a2c5f8282993b50d26f9719 (diff) | |
download | qtlocation-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.mm | 136 |
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 |