summaryrefslogtreecommitdiff
path: root/platform/ios/src/MGLAnnotationView.mm
diff options
context:
space:
mode:
Diffstat (limited to 'platform/ios/src/MGLAnnotationView.mm')
-rw-r--r--platform/ios/src/MGLAnnotationView.mm151
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