diff options
Diffstat (limited to 'platform/ios/src/MGLAnnotationView.mm')
-rw-r--r-- | platform/ios/src/MGLAnnotationView.mm | 151 |
1 files changed, 148 insertions, 3 deletions
diff --git a/platform/ios/src/MGLAnnotationView.mm b/platform/ios/src/MGLAnnotationView.mm index 31657dbf4e..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) id<MGLAnnotation> annotation; @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 @@ -22,6 +26,7 @@ { _reuseIdentifier = [reuseIdentifier copy]; _scalesWithViewingDistance = YES; + _enabled = YES; } return self; } @@ -37,6 +42,18 @@ self.center = self.center; } +- (void)setSelected:(BOOL)selected +{ + [self setSelected:selected animated:NO]; +} + +- (void)setSelected:(BOOL)selected animated:(BOOL)animated +{ + [self willChangeValueForKey:@"selected"]; + _selected = selected; + [self didChangeValueForKey:@"selected"]; +} + - (void)setCenter:(CGPoint)center { [self setCenter:center pitch:0]; @@ -49,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]; @@ -95,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. @@ -144,4 +289,4 @@ [self.superview accessibilityDecrement]; } -@end
\ No newline at end of file +@end |