Authored by Thomas Rasch

o Unified gesture recognizing in the map view (closes Alpstein/route-me#56)

@@ -8,28 +8,9 @@ @@ -8,28 +8,9 @@
8 8
9 #import <UIKit/UIKit.h> 9 #import <UIKit/UIKit.h>
10 10
11 -@class RMMapOverlayView, RMAnnotation;  
12 -  
13 -@protocol RMMapOverlayViewDelegate <NSObject>  
14 -@optional  
15 -  
16 -- (void)mapOverlayView:(RMMapOverlayView *)aMapOverlayView tapOnAnnotation:(RMAnnotation *)anAnnotation atPoint:(CGPoint)aPoint;  
17 -- (void)mapOverlayView:(RMMapOverlayView *)aMapOverlayView doubleTapOnAnnotation:(RMAnnotation *)anAnnotation atPoint:(CGPoint)aPoint;  
18 -- (void)mapOverlayView:(RMMapOverlayView *)aMapOverlayView tapOnLabelForAnnotation:(RMAnnotation *)anAnnotation atPoint:(CGPoint)aPoint;  
19 -- (void)mapOverlayView:(RMMapOverlayView *)aMapOverlayView doubleTapOnLabelForAnnotation:(RMAnnotation *)anAnnotation atPoint:(CGPoint)aPoint;  
20 -  
21 -- (BOOL)mapOverlayView:(RMMapOverlayView *)aMapOverlayView shouldDragAnnotation:(RMAnnotation *)anAnnotation;  
22 -- (void)mapOverlayView:(RMMapOverlayView *)aMapOverlayView didDragAnnotation:(RMAnnotation *)anAnnotation withDelta:(CGPoint)delta;  
23 -- (void)mapOverlayView:(RMMapOverlayView *)aMapOverlayView didEndDragAnnotation:(RMAnnotation *)anAnnotation;  
24 -  
25 -@end 11 +@class RMAnnotation;
26 12
27 @interface RMMapOverlayView : UIView 13 @interface RMMapOverlayView : UIView
28 -{  
29 - id <RMMapOverlayViewDelegate> delegate;  
30 -}  
31 -  
32 -@property (nonatomic, assign) id <RMMapOverlayViewDelegate> delegate;  
33 14
34 - (unsigned)sublayersCount; 15 - (unsigned)sublayersCount;
35 16
@@ -11,21 +11,7 @@ @@ -11,21 +11,7 @@
11 #import "RMAnnotation.h" 11 #import "RMAnnotation.h"
12 #import "RMPixel.h" 12 #import "RMPixel.h"
13 13
14 -@interface RMMapOverlayView ()  
15 -  
16 -- (void)handleSingleTap:(UIGestureRecognizer *)recognizer;  
17 -- (void)handleDoubleTap:(UIGestureRecognizer *)recognizer;  
18 -  
19 -@end  
20 -  
21 @implementation RMMapOverlayView 14 @implementation RMMapOverlayView
22 -{  
23 - BOOL _trackPanGesture;  
24 - CGPoint _lastTranslation;  
25 - RMAnnotation *_draggedAnnotation;  
26 -}  
27 -  
28 -@synthesize delegate;  
29 15
30 + (Class)layerClass 16 + (Class)layerClass
31 { 17 {
@@ -39,33 +25,9 @@ @@ -39,33 +25,9 @@
39 25
40 self.layer.masksToBounds = YES; 26 self.layer.masksToBounds = YES;
41 27
42 - _trackPanGesture = NO;  
43 - _lastTranslation = CGPointZero;  
44 - _draggedAnnotation = nil;  
45 -  
46 - UITapGestureRecognizer *doubleTapRecognizer = [[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleDoubleTap:)] autorelease];  
47 - doubleTapRecognizer.numberOfTapsRequired = 2;  
48 -  
49 - UITapGestureRecognizer *singleTapRecognizer = [[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleSingleTap:)] autorelease];  
50 - [singleTapRecognizer requireGestureRecognizerToFail:doubleTapRecognizer];  
51 -  
52 - UIPanGestureRecognizer *panGestureRecognizer = [[[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handlePanGesture:)] autorelease];  
53 - panGestureRecognizer.minimumNumberOfTouches = 1;  
54 - panGestureRecognizer.maximumNumberOfTouches = 1;  
55 -  
56 - [self addGestureRecognizer:singleTapRecognizer];  
57 - [self addGestureRecognizer:doubleTapRecognizer];  
58 - [self addGestureRecognizer:panGestureRecognizer];  
59 -  
60 return self; 28 return self;
61 } 29 }
62 30
63 -- (void)dealloc  
64 -{  
65 - [_draggedAnnotation release]; _draggedAnnotation = nil;  
66 - [super dealloc];  
67 -}  
68 -  
69 - (unsigned)sublayersCount 31 - (unsigned)sublayersCount
70 { 32 {
71 return [self.layer.sublayers count]; 33 return [self.layer.sublayers count];
@@ -96,135 +58,4 @@ @@ -96,135 +58,4 @@
96 [self.layer scrollPoint:CGPointMake(-delta.x, -delta.y)]; 58 [self.layer scrollPoint:CGPointMake(-delta.x, -delta.y)];
97 } 59 }
98 60
99 -#pragma mark -  
100 -#pragma mark Event handling  
101 -  
102 -- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event  
103 -{  
104 - if ([[event touchesForView:self] count] > 1)  
105 - return NO;  
106 -  
107 - CALayer *hit = [self.layer hitTest:point];  
108 -  
109 - RMAnnotation *hitAnnotation = [self findAnnotationInLayer:hit];  
110 -  
111 - if (!hit || !hitAnnotation || ![hitAnnotation.layer isKindOfClass:[RMMarker class]])  
112 - return NO;  
113 -  
114 - return hitAnnotation.enabled;  
115 -}  
116 -  
117 -- (RMAnnotation *)findAnnotationInLayer:(CALayer *)layer  
118 -{  
119 - if ([layer respondsToSelector:@selector(annotation)])  
120 - return [((RMMarker *)layer) annotation];  
121 -  
122 - CALayer *superlayer = [layer superlayer];  
123 -  
124 - if (superlayer != nil && [superlayer respondsToSelector:@selector(annotation)])  
125 - return [((RMMarker *)superlayer) annotation];  
126 - else if ([superlayer superlayer] != nil && [[superlayer superlayer] respondsToSelector:@selector(annotation)])  
127 - return [((RMMarker *)[superlayer superlayer]) annotation];  
128 -  
129 - return nil;  
130 -}  
131 -  
132 -- (void)handleSingleTap:(UIGestureRecognizer *)recognizer  
133 -{  
134 - CALayer *hit = [self.layer hitTest:[recognizer locationInView:self]];  
135 -  
136 - if (!hit)  
137 - return;  
138 -  
139 - CALayer *superlayer = [hit superlayer];  
140 -  
141 - // See if tap was on a marker or marker label and send delegate protocol method  
142 - if ([hit isKindOfClass:[RMMarker class]])  
143 - {  
144 - if ([delegate respondsToSelector:@selector(mapOverlayView:tapOnAnnotation:atPoint:)])  
145 - [delegate mapOverlayView:self tapOnAnnotation:[((RMMarker *)hit) annotation] atPoint:[recognizer locationInView:self]];  
146 - }  
147 - else if (superlayer != nil && [superlayer isKindOfClass:[RMMarker class]])  
148 - {  
149 - if ([delegate respondsToSelector:@selector(mapOverlayView:tapOnLabelForAnnotation:atPoint:)])  
150 - [delegate mapOverlayView:self tapOnLabelForAnnotation:[((RMMarker *)superlayer) annotation] atPoint:[recognizer locationInView:self]];  
151 - }  
152 - else if ([superlayer superlayer] != nil && [[superlayer superlayer] isKindOfClass:[RMMarker class]])  
153 - {  
154 - if ([delegate respondsToSelector:@selector(mapOverlayView:tapOnLabelForAnnotation:atPoint:)])  
155 - [delegate mapOverlayView:self tapOnLabelForAnnotation:[((RMMarker *)[superlayer superlayer]) annotation] atPoint:[recognizer locationInView:self]];  
156 - }  
157 -}  
158 -  
159 -- (void)handleDoubleTap:(UIGestureRecognizer *)recognizer  
160 -{  
161 - CALayer *hit = [self.layer hitTest:[recognizer locationInView:self]];  
162 -  
163 - if (!hit)  
164 - return;  
165 -  
166 - CALayer *superlayer = [hit superlayer];  
167 -  
168 - // See if tap was on a marker or marker label and send delegate protocol method  
169 - if ([hit isKindOfClass:[RMMarker class]])  
170 - {  
171 - if ([delegate respondsToSelector:@selector(mapOverlayView:doubleTapOnAnnotation:atPoint:)])  
172 - [delegate mapOverlayView:self doubleTapOnAnnotation:[((RMMarker *)hit) annotation] atPoint:[recognizer locationInView:self]];  
173 - }  
174 - else if (superlayer != nil && [superlayer isKindOfClass:[RMMarker class]])  
175 - {  
176 - if ([delegate respondsToSelector:@selector(mapOverlayView:doubleTapOnLabelForAnnotation:atPoint:)])  
177 - [delegate mapOverlayView:self doubleTapOnLabelForAnnotation:[((RMMarker *)superlayer) annotation] atPoint:[recognizer locationInView:self]];  
178 - }  
179 - else if ([superlayer superlayer] != nil && [[superlayer superlayer] isKindOfClass:[RMMarker class]])  
180 - {  
181 - if ([delegate respondsToSelector:@selector(mapOverlayView:doubleTapOnLabelForAnnotation:atPoint:)])  
182 - [delegate mapOverlayView:self doubleTapOnLabelForAnnotation:[((RMMarker *)[superlayer superlayer]) annotation] atPoint:[recognizer locationInView:self]];  
183 - }  
184 -}  
185 -  
186 -- (void)handlePanGesture:(UIPanGestureRecognizer *)recognizer  
187 -{  
188 - if (recognizer.state == UIGestureRecognizerStateBegan)  
189 - {  
190 - CALayer *hit = [self.layer hitTest:[recognizer locationInView:self]];  
191 -  
192 - if (!hit)  
193 - return;  
194 -  
195 - if ([hit respondsToSelector:@selector(enableDragging)] && ![(RMMarker *)hit enableDragging])  
196 - return;  
197 -  
198 - _lastTranslation = CGPointZero;  
199 - [_draggedAnnotation release];  
200 - _draggedAnnotation = [[self findAnnotationInLayer:hit] retain];  
201 -  
202 - if ([delegate respondsToSelector:@selector(mapOverlayView:shouldDragAnnotation:)])  
203 - _trackPanGesture = [delegate mapOverlayView:self shouldDragAnnotation:_draggedAnnotation];  
204 - else  
205 - _trackPanGesture = NO;  
206 - }  
207 -  
208 - if (!_trackPanGesture)  
209 - return;  
210 -  
211 - if (recognizer.state == UIGestureRecognizerStateChanged && [delegate respondsToSelector:@selector(mapOverlayView:didDragAnnotation:withDelta:)])  
212 - {  
213 - CGPoint translation = [recognizer translationInView:self];  
214 - CGPoint delta = CGPointMake(_lastTranslation.x - translation.x, _lastTranslation.y - translation.y);  
215 - _lastTranslation = translation;  
216 -  
217 - [CATransaction begin];  
218 - [CATransaction setAnimationDuration:0];  
219 - [delegate mapOverlayView:self didDragAnnotation:_draggedAnnotation withDelta:delta];  
220 - [CATransaction commit];  
221 - }  
222 - else if (recognizer.state == UIGestureRecognizerStateEnded && [delegate respondsToSelector:@selector(mapOverlayView:didEndDragAnnotation:)])  
223 - {  
224 - [delegate mapOverlayView:self didEndDragAnnotation:_draggedAnnotation];  
225 - _trackPanGesture = NO;  
226 - [_draggedAnnotation release]; _draggedAnnotation = nil;  
227 - }  
228 -}  
229 -  
230 @end 61 @end
@@ -8,24 +8,10 @@ @@ -8,24 +8,10 @@
8 8
9 #import "RMTileSource.h" 9 #import "RMTileSource.h"
10 10
11 -@class RMMapView, RMMapTiledLayerView;  
12 -  
13 -@protocol RMMapTiledLayerViewDelegate <NSObject>  
14 -@optional  
15 -  
16 -// points are in the mapview coordinate space  
17 -- (void)mapTiledLayerView:(RMMapTiledLayerView *)aTiledLayerView singleTapAtPoint:(CGPoint)aPoint;  
18 -- (void)mapTiledLayerView:(RMMapTiledLayerView *)aTiledLayerView doubleTapAtPoint:(CGPoint)aPoint;  
19 -- (void)mapTiledLayerView:(RMMapTiledLayerView *)aTiledLayerView twoFingerSingleTapAtPoint:(CGPoint)aPoint;  
20 -- (void)mapTiledLayerView:(RMMapTiledLayerView *)aTiledLayerView twoFingerDoubleTapAtPoint:(CGPoint)aPoint;  
21 -- (void)mapTiledLayerView:(RMMapTiledLayerView *)aTiledLayerView longPressAtPoint:(CGPoint)aPoint;  
22 -  
23 -@end 11 +@class RMMapView;
24 12
25 @interface RMMapTiledLayerView : UIView 13 @interface RMMapTiledLayerView : UIView
26 14
27 -@property (nonatomic, assign) id <RMMapTiledLayerViewDelegate> delegate;  
28 -  
29 @property (nonatomic, assign) BOOL useSnapshotRenderer; 15 @property (nonatomic, assign) BOOL useSnapshotRenderer;
30 16
31 @property (nonatomic, readonly) id <RMTileSource> tileSource; 17 @property (nonatomic, readonly) id <RMTileSource> tileSource;
@@ -12,20 +12,12 @@ @@ -12,20 +12,12 @@
12 #import "RMTileSource.h" 12 #import "RMTileSource.h"
13 #import "RMTileImage.h" 13 #import "RMTileImage.h"
14 14
15 -@interface RMMapOverlayView ()  
16 -  
17 -- (void)handleDoubleTap:(UIGestureRecognizer *)recognizer;  
18 -- (void)handleTwoFingerDoubleTap:(UIGestureRecognizer *)recognizer;  
19 -  
20 -@end  
21 -  
22 @implementation RMMapTiledLayerView 15 @implementation RMMapTiledLayerView
23 { 16 {
24 RMMapView *_mapView; 17 RMMapView *_mapView;
25 id <RMTileSource> _tileSource; 18 id <RMTileSource> _tileSource;
26 } 19 }
27 20
28 -@synthesize delegate = _delegate;  
29 @synthesize useSnapshotRenderer = _useSnapshotRenderer; 21 @synthesize useSnapshotRenderer = _useSnapshotRenderer;
30 @synthesize tileSource = _tileSource; 22 @synthesize tileSource = _tileSource;
31 23
@@ -44,13 +36,11 @@ @@ -44,13 +36,11 @@
44 if (!(self = [super initWithFrame:frame])) 36 if (!(self = [super initWithFrame:frame]))
45 return nil; 37 return nil;
46 38
  39 + self.opaque = NO;
  40 +
47 _mapView = [aMapView retain]; 41 _mapView = [aMapView retain];
48 _tileSource = [aTileSource retain]; 42 _tileSource = [aTileSource retain];
49 43
50 - self.userInteractionEnabled = YES;  
51 - self.multipleTouchEnabled = YES;  
52 - self.opaque = NO;  
53 -  
54 self.useSnapshotRenderer = NO; 44 self.useSnapshotRenderer = NO;
55 45
56 CATiledLayer *tiledLayer = [self tiledLayer]; 46 CATiledLayer *tiledLayer = [self tiledLayer];
@@ -59,28 +49,6 @@ @@ -59,28 +49,6 @@
59 tiledLayer.levelsOfDetail = levelsOf2xMagnification; 49 tiledLayer.levelsOfDetail = levelsOf2xMagnification;
60 tiledLayer.levelsOfDetailBias = levelsOf2xMagnification; 50 tiledLayer.levelsOfDetailBias = levelsOf2xMagnification;
61 51
62 - UITapGestureRecognizer *doubleTapRecognizer = [[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleDoubleTap:)] autorelease];  
63 - doubleTapRecognizer.numberOfTapsRequired = 2;  
64 -  
65 - UITapGestureRecognizer *singleTapRecognizer = [[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleSingleTap:)] autorelease];  
66 - [singleTapRecognizer requireGestureRecognizerToFail:doubleTapRecognizer];  
67 -  
68 - UITapGestureRecognizer *twoFingerDoubleTapRecognizer = [[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTwoFingerDoubleTap:)] autorelease];  
69 - twoFingerDoubleTapRecognizer.numberOfTapsRequired = 2;  
70 - twoFingerDoubleTapRecognizer.numberOfTouchesRequired = 2;  
71 -  
72 - UITapGestureRecognizer *twoFingerSingleTapRecognizer = [[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTwoFingerSingleTap:)] autorelease];  
73 - twoFingerSingleTapRecognizer.numberOfTouchesRequired = 2;  
74 - [twoFingerSingleTapRecognizer requireGestureRecognizerToFail:twoFingerDoubleTapRecognizer];  
75 -  
76 - UILongPressGestureRecognizer *longPressRecognizer = [[[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(handleLongPress:)] autorelease];  
77 -  
78 - [self addGestureRecognizer:singleTapRecognizer];  
79 - [self addGestureRecognizer:doubleTapRecognizer];  
80 - [self addGestureRecognizer:twoFingerDoubleTapRecognizer];  
81 - [self addGestureRecognizer:twoFingerSingleTapRecognizer];  
82 - [self addGestureRecognizer:longPressRecognizer];  
83 -  
84 return self; 52 return self;
85 } 53 }
86 54
@@ -234,39 +202,4 @@ @@ -234,39 +202,4 @@
234 [pool release]; pool = nil; 202 [pool release]; pool = nil;
235 } 203 }
236 204
237 -#pragma mark -  
238 -#pragma mark Event handling  
239 -  
240 -- (void)handleSingleTap:(UIGestureRecognizer *)recognizer  
241 -{  
242 - if ([_delegate respondsToSelector:@selector(mapTiledLayerView:singleTapAtPoint:)])  
243 - [_delegate mapTiledLayerView:self singleTapAtPoint:[recognizer locationInView:_mapView]];  
244 -}  
245 -  
246 -- (void)handleTwoFingerSingleTap:(UIGestureRecognizer *)recognizer  
247 -{  
248 - if ([_delegate respondsToSelector:@selector(mapTiledLayerView:twoFingerSingleTapAtPoint:)])  
249 - [_delegate mapTiledLayerView:self twoFingerSingleTapAtPoint:[recognizer locationInView:_mapView]];  
250 -}  
251 -  
252 -- (void)handleLongPress:(UILongPressGestureRecognizer *)recognizer  
253 -{  
254 - if (recognizer.state != UIGestureRecognizerStateBegan) return;  
255 -  
256 - if ([_delegate respondsToSelector:@selector(mapTiledLayerView:longPressAtPoint:)])  
257 - [_delegate mapTiledLayerView:self longPressAtPoint:[recognizer locationInView:_mapView]];  
258 -}  
259 -  
260 -- (void)handleDoubleTap:(UIGestureRecognizer *)recognizer  
261 -{  
262 - if ([_delegate respondsToSelector:@selector(mapTiledLayerView:doubleTapAtPoint:)])  
263 - [_delegate mapTiledLayerView:self doubleTapAtPoint:[recognizer locationInView:_mapView]];  
264 -}  
265 -  
266 -- (void)handleTwoFingerDoubleTap:(UIGestureRecognizer *)recognizer  
267 -{  
268 - if ([_delegate respondsToSelector:@selector(mapTiledLayerView:twoFingerDoubleTapAtPoint:)])  
269 - [_delegate mapTiledLayerView:self twoFingerDoubleTapAtPoint:[recognizer locationInView:_mapView]];  
270 -}  
271 -  
272 @end 205 @end
@@ -64,8 +64,7 @@ typedef enum : NSUInteger { @@ -64,8 +64,7 @@ typedef enum : NSUInteger {
64 } RMMapDecelerationMode; 64 } RMMapDecelerationMode;
65 65
66 66
67 -@interface RMMapView : UIView <UIScrollViewDelegate, RMMapOverlayViewDelegate,  
68 - RMMapTiledLayerViewDelegate, RMMapScrollViewDelegate> 67 +@interface RMMapView : UIView <UIScrollViewDelegate, UIGestureRecognizerDelegate, RMMapScrollViewDelegate>
69 68
70 @property (nonatomic, assign) id <RMMapViewDelegate> delegate; 69 @property (nonatomic, assign) id <RMMapViewDelegate> delegate;
71 70
@@ -119,6 +119,9 @@ @@ -119,6 +119,9 @@
119 BOOL _mapScrollViewIsZooming; 119 BOOL _mapScrollViewIsZooming;
120 120
121 BOOL _enableDragging, _enableBouncing; 121 BOOL _enableDragging, _enableBouncing;
  122 +
  123 + CGPoint _lastDraggingTranslation;
  124 + RMAnnotation *_draggedAnnotation;
122 } 125 }
123 126
124 @synthesize decelerationMode = _decelerationMode; 127 @synthesize decelerationMode = _decelerationMode;
@@ -149,6 +152,9 @@ @@ -149,6 +152,9 @@
149 _constrainMovement = _enableBouncing = _zoomingInPivotsAroundCenter = NO; 152 _constrainMovement = _enableBouncing = _zoomingInPivotsAroundCenter = NO;
150 _enableDragging = YES; 153 _enableDragging = YES;
151 154
  155 + _lastDraggingTranslation = CGPointZero;
  156 + _draggedAnnotation = nil;
  157 +
152 self.backgroundColor = [UIColor grayColor]; 158 self.backgroundColor = [UIColor grayColor];
153 159
154 _tileSourcesContainer = [RMTileSourcesContainer new]; 160 _tileSourcesContainer = [RMTileSourcesContainer new];
@@ -293,6 +299,7 @@ @@ -293,6 +299,7 @@
293 [self setDelegate:nil]; 299 [self setDelegate:nil];
294 [self setBackgroundView:nil]; 300 [self setBackgroundView:nil];
295 [self setQuadTree:nil]; 301 [self setQuadTree:nil];
  302 + [_draggedAnnotation release]; _draggedAnnotation = nil;
296 [_annotations release]; _annotations = nil; 303 [_annotations release]; _annotations = nil;
297 [_visibleAnnotations release]; _visibleAnnotations = nil; 304 [_visibleAnnotations release]; _visibleAnnotations = nil;
298 [[NSNotificationCenter defaultCenter] removeObserver:self]; 305 [[NSNotificationCenter defaultCenter] removeObserver:self];
@@ -925,11 +932,11 @@ @@ -925,11 +932,11 @@
925 _mapScrollView.contentOffset = CGPointMake(0.0, 0.0); 932 _mapScrollView.contentOffset = CGPointMake(0.0, 0.0);
926 933
927 _tiledLayersSuperview = [[UIView alloc] initWithFrame:CGRectMake(0.0, 0.0, contentSize.width, contentSize.height)]; 934 _tiledLayersSuperview = [[UIView alloc] initWithFrame:CGRectMake(0.0, 0.0, contentSize.width, contentSize.height)];
  935 + _tiledLayersSuperview.userInteractionEnabled = NO;
928 936
929 for (id <RMTileSource> tileSource in _tileSourcesContainer.tileSources) 937 for (id <RMTileSource> tileSource in _tileSourcesContainer.tileSources)
930 { 938 {
931 RMMapTiledLayerView *tiledLayerView = [[RMMapTiledLayerView alloc] initWithFrame:CGRectMake(0.0, 0.0, contentSize.width, contentSize.height) mapView:self forTileSource:tileSource]; 939 RMMapTiledLayerView *tiledLayerView = [[RMMapTiledLayerView alloc] initWithFrame:CGRectMake(0.0, 0.0, contentSize.width, contentSize.height) mapView:self forTileSource:tileSource];
932 - tiledLayerView.delegate = self;  
933 940
934 if (self.adjustTilesForRetinaDisplay && _screenScale > 1.0) 941 if (self.adjustTilesForRetinaDisplay && _screenScale > 1.0)
935 ((CATiledLayer *)tiledLayerView.layer).tileSize = CGSizeMake(tileSideLength * 2.0, tileSideLength * 2.0); 942 ((CATiledLayer *)tiledLayerView.layer).tileSize = CGSizeMake(tileSideLength * 2.0, tileSideLength * 2.0);
@@ -950,7 +957,6 @@ @@ -950,7 +957,6 @@
950 _mapScrollView.mapScrollViewDelegate = self; 957 _mapScrollView.mapScrollViewDelegate = self;
951 958
952 _mapScrollView.zoomScale = exp2f([self zoom]); 959 _mapScrollView.zoomScale = exp2f([self zoom]);
953 -  
954 [self setDecelerationMode:_decelerationMode]; 960 [self setDecelerationMode:_decelerationMode];
955 961
956 if (_backgroundView) 962 if (_backgroundView)
@@ -959,10 +965,52 @@ @@ -959,10 +965,52 @@
959 [self insertSubview:_mapScrollView atIndex:0]; 965 [self insertSubview:_mapScrollView atIndex:0];
960 966
961 _overlayView = [[RMMapOverlayView alloc] initWithFrame:[self bounds]]; 967 _overlayView = [[RMMapOverlayView alloc] initWithFrame:[self bounds]];
962 - _overlayView.delegate = self; 968 + _overlayView.userInteractionEnabled = NO;
963 969
964 [self insertSubview:_overlayView aboveSubview:_mapScrollView]; 970 [self insertSubview:_overlayView aboveSubview:_mapScrollView];
965 971
  972 + // add gesture recognizers
  973 +
  974 + // one finger taps
  975 + UITapGestureRecognizer *doubleTapRecognizer = [[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleDoubleTap:)] autorelease];
  976 + doubleTapRecognizer.numberOfTouchesRequired = 1;
  977 + doubleTapRecognizer.numberOfTapsRequired = 2;
  978 +
  979 + UITapGestureRecognizer *singleTapRecognizer = [[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleSingleTap:)] autorelease];
  980 + singleTapRecognizer.numberOfTouchesRequired = 1;
  981 + [singleTapRecognizer requireGestureRecognizerToFail:doubleTapRecognizer];
  982 +
  983 + UILongPressGestureRecognizer *longPressRecognizer = [[[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(handleLongPress:)] autorelease];
  984 +
  985 + [self addGestureRecognizer:singleTapRecognizer];
  986 + [self addGestureRecognizer:doubleTapRecognizer];
  987 + [self addGestureRecognizer:longPressRecognizer];
  988 +
  989 + // two finger taps
  990 + UITapGestureRecognizer *twoFingerDoubleTapRecognizer = [[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTwoFingerDoubleTap:)] autorelease];
  991 + twoFingerDoubleTapRecognizer.numberOfTapsRequired = 2;
  992 + twoFingerDoubleTapRecognizer.numberOfTouchesRequired = 2;
  993 +
  994 + UITapGestureRecognizer *twoFingerSingleTapRecognizer = [[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTwoFingerSingleTap:)] autorelease];
  995 + twoFingerSingleTapRecognizer.numberOfTouchesRequired = 2;
  996 + [twoFingerSingleTapRecognizer requireGestureRecognizerToFail:twoFingerDoubleTapRecognizer];
  997 +
  998 + [self addGestureRecognizer:twoFingerSingleTapRecognizer];
  999 + [self addGestureRecognizer:twoFingerDoubleTapRecognizer];
  1000 +
  1001 + // pan
  1002 + UIPanGestureRecognizer *panGestureRecognizer = [[[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handlePanGesture:)] autorelease];
  1003 + panGestureRecognizer.minimumNumberOfTouches = 1;
  1004 + panGestureRecognizer.maximumNumberOfTouches = 1;
  1005 +
  1006 + // the delegate is used to decide whether a pan should be handled by this
  1007 + // recognizer or by the pan gesture recognizer of the scrollview
  1008 + panGestureRecognizer.delegate = self;
  1009 +
  1010 + // the pan recognizer is added to the scrollview as it competes with the
  1011 + // pan recognizer of the scrollview
  1012 + [_mapScrollView addGestureRecognizer:panGestureRecognizer];
  1013 +
966 [_visibleAnnotations removeAllObjects]; 1014 [_visibleAnnotations removeAllObjects];
967 [self correctPositionOfAllAnnotations]; 1015 [self correctPositionOfAllAnnotations];
968 } 1016 }
@@ -1025,127 +1073,6 @@ @@ -1025,127 +1073,6 @@
1025 [_delegate afterMapZoom:self]; 1073 [_delegate afterMapZoom:self];
1026 } 1074 }
1027 1075
1028 -// Overlay  
1029 -  
1030 -- (void)mapOverlayView:(RMMapOverlayView *)aMapOverlayView tapOnAnnotation:(RMAnnotation *)anAnnotation atPoint:(CGPoint)aPoint  
1031 -{  
1032 - if (_delegateHasTapOnAnnotation && anAnnotation)  
1033 - {  
1034 - [_delegate tapOnAnnotation:anAnnotation onMap:self];  
1035 - }  
1036 - else  
1037 - {  
1038 - if (_delegateHasSingleTapOnMap)  
1039 - [_delegate singleTapOnMap:self at:aPoint];  
1040 - }  
1041 -}  
1042 -  
1043 -- (void)mapOverlayView:(RMMapOverlayView *)aMapOverlayView doubleTapOnAnnotation:(RMAnnotation *)anAnnotation atPoint:(CGPoint)aPoint  
1044 -{  
1045 - if (_delegateHasDoubleTapOnAnnotation && anAnnotation)  
1046 - {  
1047 - [_delegate doubleTapOnAnnotation:anAnnotation onMap:self];  
1048 - }  
1049 - else  
1050 - {  
1051 - [self mapTiledLayerView:[_tiledLayersSuperview.subviews lastObject] doubleTapAtPoint:aPoint];  
1052 - }  
1053 -}  
1054 -  
1055 -- (void)mapOverlayView:(RMMapOverlayView *)aMapOverlayView tapOnLabelForAnnotation:(RMAnnotation *)anAnnotation atPoint:(CGPoint)aPoint  
1056 -{  
1057 - if (_delegateHasTapOnLabelForAnnotation && anAnnotation)  
1058 - {  
1059 - [_delegate tapOnLabelForAnnotation:anAnnotation onMap:self];  
1060 - }  
1061 - else if (_delegateHasTapOnAnnotation && anAnnotation)  
1062 - {  
1063 - [_delegate tapOnAnnotation:anAnnotation onMap:self];  
1064 - }  
1065 - else  
1066 - {  
1067 - if (_delegateHasSingleTapOnMap)  
1068 - [_delegate singleTapOnMap:self at:aPoint];  
1069 - }  
1070 -}  
1071 -  
1072 -- (void)mapOverlayView:(RMMapOverlayView *)aMapOverlayView doubleTapOnLabelForAnnotation:(RMAnnotation *)anAnnotation atPoint:(CGPoint)aPoint  
1073 -{  
1074 - if (_delegateHasDoubleTapOnLabelForAnnotation && anAnnotation)  
1075 - {  
1076 - [_delegate doubleTapOnLabelForAnnotation:anAnnotation onMap:self];  
1077 - }  
1078 - else if (_delegateHasDoubleTapOnAnnotation && anAnnotation)  
1079 - {  
1080 - [_delegate doubleTapOnAnnotation:anAnnotation onMap:self];  
1081 - }  
1082 - else  
1083 - {  
1084 - [self mapTiledLayerView:[_tiledLayersSuperview.subviews lastObject] doubleTapAtPoint:aPoint];  
1085 - }  
1086 -}  
1087 -  
1088 -- (BOOL)mapOverlayView:(RMMapOverlayView *)aMapOverlayView shouldDragAnnotation:(RMAnnotation *)anAnnotation  
1089 -{  
1090 - if (_delegateHasShouldDragMarker)  
1091 - return [_delegate mapView:self shouldDragAnnotation:anAnnotation];  
1092 - else  
1093 - return NO;  
1094 -}  
1095 -  
1096 -- (void)mapOverlayView:(RMMapOverlayView *)aMapOverlayView didDragAnnotation:(RMAnnotation *)anAnnotation withDelta:(CGPoint)delta  
1097 -{  
1098 - if (_delegateHasDidDragMarker)  
1099 - [_delegate mapView:self didDragAnnotation:anAnnotation withDelta:delta];  
1100 -}  
1101 -  
1102 -- (void)mapOverlayView:(RMMapOverlayView *)aMapOverlayView didEndDragAnnotation:(RMAnnotation *)anAnnotation  
1103 -{  
1104 - if (_delegateHasDidEndDragMarker)  
1105 - [_delegate mapView:self didEndDragAnnotation:anAnnotation];  
1106 -}  
1107 -  
1108 -// Tiled layer  
1109 -  
1110 -- (void)mapTiledLayerView:(RMMapTiledLayerView *)aTiledLayerView singleTapAtPoint:(CGPoint)aPoint  
1111 -{  
1112 - if (_delegateHasSingleTapOnMap)  
1113 - [_delegate singleTapOnMap:self at:aPoint];  
1114 -}  
1115 -  
1116 -- (void)mapTiledLayerView:(RMMapTiledLayerView *)aTiledLayerView doubleTapAtPoint:(CGPoint)aPoint  
1117 -{  
1118 - if (self.zoomingInPivotsAroundCenter)  
1119 - [self zoomInToNextNativeZoomAt:[self convertPoint:self.center fromView:self.superview] animated:YES];  
1120 - else  
1121 - [self zoomInToNextNativeZoomAt:aPoint animated:YES];  
1122 -  
1123 - if (_delegateHasDoubleTapOnMap)  
1124 - [_delegate doubleTapOnMap:self at:aPoint];  
1125 -}  
1126 -  
1127 -- (void)mapTiledLayerView:(RMMapTiledLayerView *)aTiledLayerView twoFingerDoubleTapAtPoint:(CGPoint)aPoint  
1128 -{  
1129 - [self zoomOutToNextNativeZoomAt:[self convertPoint:self.center fromView:self.superview] animated:YES];  
1130 -  
1131 - if (_delegateHasDoubleTapTwoFingersOnMap)  
1132 - [_delegate doubleTapTwoFingersOnMap:self at:aPoint];  
1133 -}  
1134 -  
1135 -- (void)mapTiledLayerView:(RMMapTiledLayerView *)aTiledLayerView twoFingerSingleTapAtPoint:(CGPoint)aPoint  
1136 -{  
1137 - [self zoomOutToNextNativeZoomAt:[self convertPoint:self.center fromView:self.superview] animated:YES];  
1138 -  
1139 - if (_delegateHasSingleTapTwoFingersOnMap)  
1140 - [_delegate singleTapTwoFingersOnMap:self at:aPoint];  
1141 -}  
1142 -  
1143 -- (void)mapTiledLayerView:(RMMapTiledLayerView *)aTiledLayerView longPressAtPoint:(CGPoint)aPoint  
1144 -{  
1145 - if (_delegateHasLongSingleTapOnMap)  
1146 - [_delegate longSingleTapOnMap:self at:aPoint];  
1147 -}  
1148 -  
1149 // Detect dragging/zooming 1076 // Detect dragging/zooming
1150 1077
1151 - (void)scrollView:(RMMapScrollView *)aScrollView correctedContentOffset:(inout CGPoint *)aContentOffset 1078 - (void)scrollView:(RMMapScrollView *)aScrollView correctedContentOffset:(inout CGPoint *)aContentOffset
@@ -1285,6 +1212,260 @@ @@ -1285,6 +1212,260 @@
1285 [_delegate mapViewRegionDidChange:self]; 1212 [_delegate mapViewRegionDidChange:self];
1286 } 1213 }
1287 1214
  1215 +#pragma mark - Gesture Recognizers and event handling
  1216 +
  1217 +- (RMAnnotation *)findAnnotationInLayer:(CALayer *)layer
  1218 +{
  1219 + if ([layer respondsToSelector:@selector(annotation)])
  1220 + return [((RMMarker *)layer) annotation];
  1221 +
  1222 + CALayer *superlayer = [layer superlayer];
  1223 +
  1224 + if (superlayer != nil && [superlayer respondsToSelector:@selector(annotation)])
  1225 + return [((RMMarker *)superlayer) annotation];
  1226 + else if ([superlayer superlayer] != nil && [[superlayer superlayer] respondsToSelector:@selector(annotation)])
  1227 + return [((RMMarker *)[superlayer superlayer]) annotation];
  1228 +
  1229 + return nil;
  1230 +}
  1231 +
  1232 +- (void)singleTapAtPoint:(CGPoint)aPoint
  1233 +{
  1234 + if (_delegateHasSingleTapOnMap)
  1235 + [_delegate singleTapOnMap:self at:aPoint];
  1236 +}
  1237 +
  1238 +- (void)handleSingleTap:(UIGestureRecognizer *)recognizer
  1239 +{
  1240 + CALayer *hit = [_overlayView.layer hitTest:[recognizer locationInView:_overlayView]];
  1241 +
  1242 + if ( ! hit)
  1243 + {
  1244 + [self singleTapAtPoint:[recognizer locationInView:self]];
  1245 + return;
  1246 + }
  1247 +
  1248 + CALayer *superlayer = [hit superlayer];
  1249 +
  1250 + // See if tap was on a marker or marker label and send delegate protocol method
  1251 + if ([hit isKindOfClass:[RMMarker class]])
  1252 + {
  1253 + [self tapOnAnnotation:[((RMMarker *)hit) annotation] atPoint:[recognizer locationInView:self]];
  1254 + }
  1255 + else if (superlayer != nil && [superlayer isKindOfClass:[RMMarker class]])
  1256 + {
  1257 + [self tapOnLabelForAnnotation:[((RMMarker *)superlayer) annotation] atPoint:[recognizer locationInView:self]];
  1258 + }
  1259 + else if ([superlayer superlayer] != nil && [[superlayer superlayer] isKindOfClass:[RMMarker class]])
  1260 + {
  1261 + [self tapOnLabelForAnnotation:[((RMMarker *)[superlayer superlayer]) annotation] atPoint:[recognizer locationInView:self]];
  1262 + }
  1263 + else
  1264 + {
  1265 + [self singleTapAtPoint:[recognizer locationInView:self]];
  1266 + }
  1267 +}
  1268 +
  1269 +- (void)doubleTapAtPoint:(CGPoint)aPoint
  1270 +{
  1271 + if (self.zoomingInPivotsAroundCenter)
  1272 + [self zoomInToNextNativeZoomAt:[self convertPoint:self.center fromView:self.superview] animated:YES];
  1273 + else
  1274 + [self zoomInToNextNativeZoomAt:aPoint animated:YES];
  1275 +
  1276 + if (_delegateHasDoubleTapOnMap)
  1277 + [_delegate doubleTapOnMap:self at:aPoint];
  1278 +}
  1279 +
  1280 +- (void)handleDoubleTap:(UIGestureRecognizer *)recognizer
  1281 +{
  1282 + CALayer *hit = [_overlayView.layer hitTest:[recognizer locationInView:_overlayView]];
  1283 +
  1284 + if ( ! hit)
  1285 + {
  1286 + [self doubleTapAtPoint:[recognizer locationInView:self]];
  1287 + return;
  1288 + }
  1289 +
  1290 + CALayer *superlayer = [hit superlayer];
  1291 +
  1292 + // See if tap was on a marker or marker label and send delegate protocol method
  1293 + if ([hit isKindOfClass:[RMMarker class]])
  1294 + {
  1295 + [self doubleTapOnAnnotation:[((RMMarker *)hit) annotation] atPoint:[recognizer locationInView:self]];
  1296 + }
  1297 + else if (superlayer != nil && [superlayer isKindOfClass:[RMMarker class]])
  1298 + {
  1299 + [self doubleTapOnLabelForAnnotation:[((RMMarker *)superlayer) annotation] atPoint:[recognizer locationInView:self]];
  1300 + }
  1301 + else if ([superlayer superlayer] != nil && [[superlayer superlayer] isKindOfClass:[RMMarker class]])
  1302 + {
  1303 + [self doubleTapOnLabelForAnnotation:[((RMMarker *)[superlayer superlayer]) annotation] atPoint:[recognizer locationInView:self]];
  1304 + }
  1305 + else
  1306 + {
  1307 + [self doubleTapAtPoint:[recognizer locationInView:self]];
  1308 + }
  1309 +}
  1310 +
  1311 +- (void)handleTwoFingerDoubleTap:(UIGestureRecognizer *)recognizer
  1312 +{
  1313 + [self zoomOutToNextNativeZoomAt:[self convertPoint:self.center fromView:self.superview] animated:YES];
  1314 +
  1315 + if (_delegateHasDoubleTapTwoFingersOnMap)
  1316 + [_delegate doubleTapTwoFingersOnMap:self at:[recognizer locationInView:self]];
  1317 +}
  1318 +
  1319 +- (void)handleTwoFingerSingleTap:(UIGestureRecognizer *)recognizer
  1320 +{
  1321 + [self zoomOutToNextNativeZoomAt:[self convertPoint:self.center fromView:self.superview] animated:YES];
  1322 +
  1323 + if (_delegateHasSingleTapTwoFingersOnMap)
  1324 + [_delegate singleTapTwoFingersOnMap:self at:[recognizer locationInView:self]];
  1325 +}
  1326 +
  1327 +- (void)handleLongPress:(UILongPressGestureRecognizer *)recognizer
  1328 +{
  1329 + if (recognizer.state != UIGestureRecognizerStateBegan)
  1330 + return;
  1331 +
  1332 + if (_delegateHasLongSingleTapOnMap)
  1333 + [_delegate longSingleTapOnMap:self at:[recognizer locationInView:self]];
  1334 +}
  1335 +
  1336 +// defines when the additional pan gesture recognizer on the scroll should handle the gesture
  1337 +- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)recognizer
  1338 +{
  1339 + if ([recognizer isKindOfClass:[UIPanGestureRecognizer class]])
  1340 + {
  1341 + // check whether our custom pan gesture recognizer should start recognizing the gesture
  1342 + CALayer *hit = [_overlayView.layer hitTest:[recognizer locationInView:_overlayView]];
  1343 +
  1344 + if (!hit || ([hit respondsToSelector:@selector(enableDragging)] && ![(RMMarker *)hit enableDragging]))
  1345 + return NO;
  1346 +
  1347 + if ( ! [self shouldDragAnnotation:[self findAnnotationInLayer:hit]])
  1348 + return NO;
  1349 + }
  1350 +
  1351 + return YES;
  1352 +}
  1353 +
  1354 +- (void)handlePanGesture:(UIPanGestureRecognizer *)recognizer
  1355 +{
  1356 + if (recognizer.state == UIGestureRecognizerStateBegan)
  1357 + {
  1358 + CALayer *hit = [_overlayView.layer hitTest:[recognizer locationInView:self]];
  1359 +
  1360 + if ( ! hit)
  1361 + return;
  1362 +
  1363 + if ([hit respondsToSelector:@selector(enableDragging)] && ![(RMMarker *)hit enableDragging])
  1364 + return;
  1365 +
  1366 + _lastDraggingTranslation = CGPointZero;
  1367 + [_draggedAnnotation release];
  1368 + _draggedAnnotation = [[self findAnnotationInLayer:hit] retain];
  1369 + }
  1370 +
  1371 + if (recognizer.state == UIGestureRecognizerStateChanged)
  1372 + {
  1373 + CGPoint translation = [recognizer translationInView:_overlayView];
  1374 + CGPoint delta = CGPointMake(_lastDraggingTranslation.x - translation.x, _lastDraggingTranslation.y - translation.y);
  1375 + _lastDraggingTranslation = translation;
  1376 +
  1377 + [CATransaction begin];
  1378 + [CATransaction setAnimationDuration:0];
  1379 + [self didDragAnnotation:_draggedAnnotation withDelta:delta];
  1380 + [CATransaction commit];
  1381 + }
  1382 + else if (recognizer.state == UIGestureRecognizerStateEnded)
  1383 + {
  1384 + [self didEndDragAnnotation:_draggedAnnotation];
  1385 + [_draggedAnnotation release]; _draggedAnnotation = nil;
  1386 + }
  1387 +}
  1388 +
  1389 +// Overlay
  1390 +
  1391 +- (void)tapOnAnnotation:(RMAnnotation *)anAnnotation atPoint:(CGPoint)aPoint
  1392 +{
  1393 + if (_delegateHasTapOnAnnotation && anAnnotation)
  1394 + {
  1395 + [_delegate tapOnAnnotation:anAnnotation onMap:self];
  1396 + }
  1397 + else
  1398 + {
  1399 + if (_delegateHasSingleTapOnMap)
  1400 + [_delegate singleTapOnMap:self at:aPoint];
  1401 + }
  1402 +}
  1403 +
  1404 +- (void)doubleTapOnAnnotation:(RMAnnotation *)anAnnotation atPoint:(CGPoint)aPoint
  1405 +{
  1406 + if (_delegateHasDoubleTapOnAnnotation && anAnnotation)
  1407 + {
  1408 + [_delegate doubleTapOnAnnotation:anAnnotation onMap:self];
  1409 + }
  1410 + else
  1411 + {
  1412 + [self doubleTapAtPoint:aPoint];
  1413 + }
  1414 +}
  1415 +
  1416 +- (void)tapOnLabelForAnnotation:(RMAnnotation *)anAnnotation atPoint:(CGPoint)aPoint
  1417 +{
  1418 + if (_delegateHasTapOnLabelForAnnotation && anAnnotation)
  1419 + {
  1420 + [_delegate tapOnLabelForAnnotation:anAnnotation onMap:self];
  1421 + }
  1422 + else if (_delegateHasTapOnAnnotation && anAnnotation)
  1423 + {
  1424 + [_delegate tapOnAnnotation:anAnnotation onMap:self];
  1425 + }
  1426 + else
  1427 + {
  1428 + if (_delegateHasSingleTapOnMap)
  1429 + [_delegate singleTapOnMap:self at:aPoint];
  1430 + }
  1431 +}
  1432 +
  1433 +- (void)doubleTapOnLabelForAnnotation:(RMAnnotation *)anAnnotation atPoint:(CGPoint)aPoint
  1434 +{
  1435 + if (_delegateHasDoubleTapOnLabelForAnnotation && anAnnotation)
  1436 + {
  1437 + [_delegate doubleTapOnLabelForAnnotation:anAnnotation onMap:self];
  1438 + }
  1439 + else if (_delegateHasDoubleTapOnAnnotation && anAnnotation)
  1440 + {
  1441 + [_delegate doubleTapOnAnnotation:anAnnotation onMap:self];
  1442 + }
  1443 + else
  1444 + {
  1445 + [self doubleTapAtPoint:aPoint];
  1446 + }
  1447 +}
  1448 +
  1449 +- (BOOL)shouldDragAnnotation:(RMAnnotation *)anAnnotation
  1450 +{
  1451 + if (_delegateHasShouldDragMarker)
  1452 + return [_delegate mapView:self shouldDragAnnotation:anAnnotation];
  1453 + else
  1454 + return NO;
  1455 +}
  1456 +
  1457 +- (void)didDragAnnotation:(RMAnnotation *)anAnnotation withDelta:(CGPoint)delta
  1458 +{
  1459 + if (_delegateHasDidDragMarker)
  1460 + [_delegate mapView:self didDragAnnotation:anAnnotation withDelta:delta];
  1461 +}
  1462 +
  1463 +- (void)didEndDragAnnotation:(RMAnnotation *)anAnnotation
  1464 +{
  1465 + if (_delegateHasDidEndDragMarker)
  1466 + [_delegate mapView:self didEndDragAnnotation:anAnnotation];
  1467 +}
  1468 +
1288 #pragma mark - 1469 #pragma mark -
1289 #pragma mark Snapshots 1470 #pragma mark Snapshots
1290 1471
@@ -1423,7 +1604,6 @@ @@ -1423,7 +1604,6 @@
1423 CGSize contentSize = CGSizeMake(tileSideLength, tileSideLength); // zoom level 1 1604 CGSize contentSize = CGSizeMake(tileSideLength, tileSideLength); // zoom level 1
1424 1605
1425 RMMapTiledLayerView *tiledLayerView = [[RMMapTiledLayerView alloc] initWithFrame:CGRectMake(0.0, 0.0, contentSize.width, contentSize.height) mapView:self forTileSource:newTileSource]; 1606 RMMapTiledLayerView *tiledLayerView = [[RMMapTiledLayerView alloc] initWithFrame:CGRectMake(0.0, 0.0, contentSize.width, contentSize.height) mapView:self forTileSource:newTileSource];
1426 - tiledLayerView.delegate = self;  
1427 1607
1428 if (self.adjustTilesForRetinaDisplay && _screenScale > 1.0) 1608 if (self.adjustTilesForRetinaDisplay && _screenScale > 1.0)
1429 ((CATiledLayer *)tiledLayerView.layer).tileSize = CGSizeMake(tileSideLength * 2.0, tileSideLength * 2.0); 1609 ((CATiledLayer *)tiledLayerView.layer).tileSize = CGSizeMake(tileSideLength * 2.0, tileSideLength * 2.0);