Authored by Thomas Rasch

o Readded marker dragging

... ... @@ -41,7 +41,7 @@
return nil;
self.annotation = nil;
self.enableDragging = YES;
self.enableDragging = NO;
return self;
}
... ...
... ... @@ -18,10 +18,17 @@
- (void)mapOverlayView:(RMMapOverlayView *)aMapOverlayView tapOnLabelForAnnotation:(RMAnnotation *)anAnnotation atPoint:(CGPoint)aPoint;
- (void)mapOverlayView:(RMMapOverlayView *)aMapOverlayView doubleTapOnLabelForAnnotation:(RMAnnotation *)anAnnotation atPoint:(CGPoint)aPoint;
- (BOOL)mapOverlayView:(RMMapOverlayView *)aMapOverlayView shouldDragAnnotation:(RMAnnotation *)anAnnotation;
- (void)mapOverlayView:(RMMapOverlayView *)aMapOverlayView didDragAnnotation:(RMAnnotation *)anAnnotation withDelta:(CGPoint)delta;
- (void)mapOverlayView:(RMMapOverlayView *)aMapOverlayView didEndDragAnnotation:(RMAnnotation *)anAnnotation;
@end
@interface RMMapOverlayView : UIView {
id <RMMapOverlayViewDelegate> delegate;
BOOL trackPanGesture;
CGPoint lastTranslation;
}
@property (nonatomic, assign) id <RMMapOverlayViewDelegate> delegate;
... ...
... ... @@ -35,8 +35,13 @@
UITapGestureRecognizer *singleTapRecognizer = [[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleSingleTap:)] autorelease];
[singleTapRecognizer requireGestureRecognizerToFail:doubleTapRecognizer];
UIPanGestureRecognizer *panGestureRecognizer = [[[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handlePanGesture:)] autorelease];
panGestureRecognizer.minimumNumberOfTouches = 1;
panGestureRecognizer.maximumNumberOfTouches = 1;
[self addGestureRecognizer:singleTapRecognizer];
[self addGestureRecognizer:doubleTapRecognizer];
[self addGestureRecognizer:panGestureRecognizer];
return self;
}
... ... @@ -90,27 +95,39 @@
return ((RMMarker *)hit).annotation.enabled;
}
- (RMAnnotation *)findAnnotationInLayer:(CALayer *)layer
{
if ([layer respondsToSelector:@selector(annotation)])
return [((RMMarker *)layer) annotation];
CALayer *superlayer = [layer superlayer];
if (superlayer != nil && [superlayer respondsToSelector:@selector(annotation)])
return [((RMMarker *)superlayer) annotation];
else if ([superlayer superlayer] != nil && [[superlayer superlayer] respondsToSelector:@selector(annotation)])
return [((RMMarker *)[superlayer superlayer]) annotation];
return nil;
}
- (void)handleSingleTap:(UIGestureRecognizer *)recognizer
{
CALayer *hit = [self.layer hitTest:[recognizer locationInView:self]];
if (!hit) return;
if (hit != nil)
{
CALayer *superlayer = [hit superlayer];
// See if tap was on a marker or marker label and send delegate protocol method
if ([hit isKindOfClass:[RMMarker class]]) {
if ([delegate respondsToSelector:@selector(mapOverlayView:tapOnAnnotation:atPoint:)]) {
[delegate mapOverlayView:self tapOnAnnotation:[((RMMarker *)hit) annotation] atPoint:[recognizer locationInView:self]];
}
} else if (superlayer != nil && [superlayer isKindOfClass:[RMMarker class]]) {
if ([delegate respondsToSelector:@selector(mapOverlayView:tapOnLabelForAnnotation:atPoint:)]) {
[delegate mapOverlayView:self tapOnLabelForAnnotation:[((RMMarker *)superlayer) annotation] atPoint:[recognizer locationInView:self]];
}
} else if ([superlayer superlayer] != nil && [[superlayer superlayer] isKindOfClass:[RMMarker class]]) {
if ([delegate respondsToSelector:@selector(mapOverlayView:tapOnLabelForAnnotation:atPoint:)]) {
[delegate mapOverlayView:self tapOnLabelForAnnotation:[((RMMarker *)[superlayer superlayer]) annotation] atPoint:[recognizer locationInView:self]];
}
CALayer *superlayer = [hit superlayer];
// See if tap was on a marker or marker label and send delegate protocol method
if ([hit isKindOfClass:[RMMarker class]]) {
if ([delegate respondsToSelector:@selector(mapOverlayView:tapOnAnnotation:atPoint:)]) {
[delegate mapOverlayView:self tapOnAnnotation:[((RMMarker *)hit) annotation] atPoint:[recognizer locationInView:self]];
}
} else if (superlayer != nil && [superlayer isKindOfClass:[RMMarker class]]) {
if ([delegate respondsToSelector:@selector(mapOverlayView:tapOnLabelForAnnotation:atPoint:)]) {
[delegate mapOverlayView:self tapOnLabelForAnnotation:[((RMMarker *)superlayer) annotation] atPoint:[recognizer locationInView:self]];
}
} else if ([superlayer superlayer] != nil && [[superlayer superlayer] isKindOfClass:[RMMarker class]]) {
if ([delegate respondsToSelector:@selector(mapOverlayView:tapOnLabelForAnnotation:atPoint:)]) {
[delegate mapOverlayView:self tapOnLabelForAnnotation:[((RMMarker *)[superlayer superlayer]) annotation] atPoint:[recognizer locationInView:self]];
}
}
}
... ... @@ -118,25 +135,52 @@
- (void)handleDoubleTap:(UIGestureRecognizer *)recognizer
{
CALayer *hit = [self.layer hitTest:[recognizer locationInView:self]];
if (!hit) return;
if (hit != nil)
{
CALayer *superlayer = [hit superlayer];
// See if tap was on a marker or marker label and send delegate protocol method
if ([hit isKindOfClass:[RMMarker class]]) {
if ([delegate respondsToSelector:@selector(mapOverlayView:doubleTapOnAnnotation:atPoint:)]) {
[delegate mapOverlayView:self doubleTapOnAnnotation:[((RMMarker *)hit) annotation] atPoint:[recognizer locationInView:self]];
}
} else if (superlayer != nil && [superlayer isKindOfClass:[RMMarker class]]) {
if ([delegate respondsToSelector:@selector(mapOverlayView:doubleTapOnLabelForAnnotation:atPoint:)]) {
[delegate mapOverlayView:self doubleTapOnLabelForAnnotation:[((RMMarker *)superlayer) annotation] atPoint:[recognizer locationInView:self]];
}
} else if ([superlayer superlayer] != nil && [[superlayer superlayer] isKindOfClass:[RMMarker class]]) {
if ([delegate respondsToSelector:@selector(mapOverlayView:doubleTapOnLabelForAnnotation:atPoint:)]) {
[delegate mapOverlayView:self doubleTapOnLabelForAnnotation:[((RMMarker *)[superlayer superlayer]) annotation] atPoint:[recognizer locationInView:self]];
}
CALayer *superlayer = [hit superlayer];
// See if tap was on a marker or marker label and send delegate protocol method
if ([hit isKindOfClass:[RMMarker class]]) {
if ([delegate respondsToSelector:@selector(mapOverlayView:doubleTapOnAnnotation:atPoint:)]) {
[delegate mapOverlayView:self doubleTapOnAnnotation:[((RMMarker *)hit) annotation] atPoint:[recognizer locationInView:self]];
}
} else if (superlayer != nil && [superlayer isKindOfClass:[RMMarker class]]) {
if ([delegate respondsToSelector:@selector(mapOverlayView:doubleTapOnLabelForAnnotation:atPoint:)]) {
[delegate mapOverlayView:self doubleTapOnLabelForAnnotation:[((RMMarker *)superlayer) annotation] atPoint:[recognizer locationInView:self]];
}
} else if ([superlayer superlayer] != nil && [[superlayer superlayer] isKindOfClass:[RMMarker class]]) {
if ([delegate respondsToSelector:@selector(mapOverlayView:doubleTapOnLabelForAnnotation:atPoint:)]) {
[delegate mapOverlayView:self doubleTapOnLabelForAnnotation:[((RMMarker *)[superlayer superlayer]) annotation] atPoint:[recognizer locationInView:self]];
}
}
}
- (void)handlePanGesture:(UIPanGestureRecognizer *)recognizer
{
CALayer *hit = [self.layer hitTest:[recognizer locationInView:self]];
if (!hit) return;
if ([hit respondsToSelector:@selector(enableDragging)] && ![(RMMarker *)hit enableDragging]) return;
if (recognizer.state == UIGestureRecognizerStateBegan) {
lastTranslation = CGPointZero;
if ([delegate respondsToSelector:@selector(mapOverlayView:shouldDragAnnotation:)])
trackPanGesture = [delegate mapOverlayView:self shouldDragAnnotation:[self findAnnotationInLayer:hit]];
else
trackPanGesture = NO;
}
if (!trackPanGesture) return;
if (recognizer.state == UIGestureRecognizerStateChanged && [delegate respondsToSelector:@selector(mapOverlayView:didDragAnnotation:withDelta:)]) {
CGPoint translation = [recognizer translationInView:self];
CGPoint delta = CGPointMake(lastTranslation.x - translation.x, lastTranslation.y - translation.y);
lastTranslation = translation;
[delegate mapOverlayView:self didDragAnnotation:[self findAnnotationInLayer:hit] withDelta:delta];
} else if (recognizer.state == UIGestureRecognizerStateEnded && [delegate respondsToSelector:@selector(mapOverlayView:didEndDragAnnotation:)]) {
[delegate mapOverlayView:self didEndDragAnnotation:[self findAnnotationInLayer:hit]];
trackPanGesture = NO;
}
}
... ...
... ... @@ -111,6 +111,7 @@ typedef enum {
BOOL _delegateHasAfterMapTouch;
BOOL _delegateHasShouldDragMarker;
BOOL _delegateHasDidDragMarker;
BOOL _delegateHasDidEndDragMarker;
BOOL _delegateHasLayerForAnnotation;
BOOL _delegateHasWillHideLayerForAnnotation;
BOOL _delegateHasDidHideLayerForAnnotation;
... ...
... ... @@ -289,8 +289,9 @@
_delegateHasTapOnLabelForAnnotation = [delegate respondsToSelector:@selector(tapOnLabelForAnnotation:onMap:)];
_delegateHasDoubleTapOnLabelForAnnotation = [delegate respondsToSelector:@selector(doubleTapOnLabelForAnnotation:onMap:)];
_delegateHasShouldDragMarker = [delegate respondsToSelector:@selector(mapView:shouldDragAnnotation:withEvent:)];
_delegateHasDidDragMarker = [delegate respondsToSelector:@selector(mapView:didDragAnnotation:withEvent:)];
_delegateHasShouldDragMarker = [delegate respondsToSelector:@selector(mapView:shouldDragAnnotation:)];
_delegateHasDidDragMarker = [delegate respondsToSelector:@selector(mapView:didDragAnnotation:withDelta:)];
_delegateHasDidEndDragMarker = [delegate respondsToSelector:@selector(mapView:didEndDragAnnotation:)];
_delegateHasLayerForAnnotation = [delegate respondsToSelector:@selector(mapView:layerForAnnotation:)];
_delegateHasWillHideLayerForAnnotation = [delegate respondsToSelector:@selector(mapView:willHideLayerForAnnotation:)];
... ... @@ -999,6 +1000,26 @@
}
}
- (BOOL)mapOverlayView:(RMMapOverlayView *)aMapOverlayView shouldDragAnnotation:(RMAnnotation *)anAnnotation
{
if (_delegateHasShouldDragMarker)
return [delegate mapView:self shouldDragAnnotation:anAnnotation];
else
return NO;
}
- (void)mapOverlayView:(RMMapOverlayView *)aMapOverlayView didDragAnnotation:(RMAnnotation *)anAnnotation withDelta:(CGPoint)delta
{
if (_delegateHasDidDragMarker)
[delegate mapView:self didDragAnnotation:anAnnotation withDelta:delta];
}
- (void)mapOverlayView:(RMMapOverlayView *)aMapOverlayView didEndDragAnnotation:(RMAnnotation *)anAnnotation
{
if (_delegateHasDidEndDragMarker)
[delegate mapView:self didEndDragAnnotation:anAnnotation];
}
// Tiled layer
- (void)mapTiledLayerView:(RMMapTiledLayerView *)aTiledLayerView singleTapAtPoint:(CGPoint)aPoint
... ... @@ -1059,6 +1080,7 @@
_lastContentOffset = mapScrollView.contentOffset;
// Don't do anything stupid here or your scrolling experience will suck
if (_delegateHasMapViewRegionDidChange) [delegate mapViewRegionDidChange:self];
}
... ...
... ... @@ -62,7 +62,8 @@
- (void)tapOnLabelForAnnotation:(RMAnnotation *)annotation onMap:(RMMapView *)map;
- (void)doubleTapOnLabelForAnnotation:(RMAnnotation *)annotation onMap:(RMMapView *)map;
- (BOOL)mapView:(RMMapView *)map shouldDragAnnotation:(RMAnnotation *)annotation withEvent:(UIEvent *)event;
- (void)mapView:(RMMapView *)map didDragAnnotation:(RMAnnotation *)annotation withEvent:(UIEvent *)event;
- (BOOL)mapView:(RMMapView *)map shouldDragAnnotation:(RMAnnotation *)annotation;
- (void)mapView:(RMMapView *)map didDragAnnotation:(RMAnnotation *)annotation withDelta:(CGPoint)delta;
- (void)mapView:(RMMapView *)map didEndDragAnnotation:(RMAnnotation *)annotation;
@end
... ...