Skip to content
This repository was archived by the owner on Feb 2, 2023. It is now read-only.

Commit e35697d

Browse files
Greatly improve the internal logic of ASMapNode. Also fixes bug #971
1 parent 4ceab33 commit e35697d

2 files changed

Lines changed: 66 additions & 57 deletions

File tree

AsyncDisplayKit/ASMapNode.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
@interface ASMapNode : ASImageNode
1313

1414
/**
15-
The current region of ASMapNode. This can be set at any time and ASMapNode will animate the change.
15+
The current region of ASMapNode. This can be set at any time and ASMapNode will animate the change. This property may be set from a background thread before the node is loaded, and will automatically be applied to define the region of the static snapshot (if .liveMap = NO) or the internal MKMapView (otherwise).
1616
*/
1717
@property (nonatomic, assign) MKCoordinateRegion region;
1818

@@ -22,7 +22,7 @@
2222
@property (nonatomic, readonly) MKMapView *mapView;
2323

2424
/**
25-
Set this to YES to turn the snapshot into an interactive MKMapView and vice versa. Defaults to NO.
25+
Set this to YES to turn the snapshot into an interactive MKMapView and vice versa. Defaults to NO. This property may be set on a background thread before the node is loaded, and will automatically be actioned, once the node is loaded.
2626
*/
2727
@property (nonatomic, assign, getter=isLiveMap) BOOL liveMap;
2828

AsyncDisplayKit/ASMapNode.mm

Lines changed: 64 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ @implementation ASMapNode
2626
@synthesize needsMapReloadOnBoundsChange = _needsMapReloadOnBoundsChange;
2727
@synthesize mapDelegate = _mapDelegate;
2828
@synthesize region = _region;
29+
@synthesize liveMap = _liveMap;
2930

3031
#pragma mark - Lifecycle
3132
- (instancetype)init
@@ -37,9 +38,11 @@ - (instancetype)init
3738
self.clipsToBounds = YES;
3839

3940
_needsMapReloadOnBoundsChange = YES;
40-
41+
_liveMap = NO;
4142
_centerCoordinateOfMap = kCLLocationCoordinate2DInvalid;
42-
_region = MKCoordinateRegionMake(CLLocationCoordinate2DMake(43.432858, 13.183671), MKCoordinateSpanMake(0.2, 0.2));
43+
44+
//Default world-scale view
45+
_region = MKCoordinateRegionForMapRect(MKMapRectWorld);
4346

4447
_options = [[MKMapSnapshotOptions alloc] init];
4548
_options.region = _region;
@@ -50,26 +53,31 @@ - (instancetype)init
5053
- (void)didLoad
5154
{
5255
[super didLoad];
53-
if ([self wasLiveMapPreviously]) {
56+
if (self.isLiveMap) {
5457
self.userInteractionEnabled = YES;
5558
[self addLiveMap];
5659
}
5760
}
5861

62+
- (void)setLayerBacked:(BOOL)layerBacked
63+
{
64+
ASDisplayNodeAssert(!self.isLiveMap, @"ASMapNode can not be layer backed whilst .liveMap = YES, set .liveMap = NO to use layer backing.");
65+
[super setLayerBacked:layerBacked];
66+
}
67+
5968
- (void)fetchData
6069
{
6170
[super fetchData];
62-
if ([self wasLiveMapPreviously]) {
71+
if (self.isLiveMap) {
6372
[self addLiveMap];
6473
} else {
65-
[self setUpSnapshotter];
6674
[self takeSnapshot];
6775
}
6876
}
6977

70-
- (void)clearFetchedData
78+
- (void)clearContents
7179
{
72-
[super clearFetchedData];
80+
[super clearContents];
7381
if (self.isLiveMap) {
7482
[self removeLiveMap];
7583
}
@@ -79,17 +87,21 @@ - (void)clearFetchedData
7987

8088
- (BOOL)isLiveMap
8189
{
82-
return (_mapView != nil);
90+
ASDN::MutexLocker l(_propertyLock);
91+
return _liveMap;
8392
}
8493

8594
- (void)setLiveMap:(BOOL)liveMap
8695
{
87-
liveMap ? [self addLiveMap] : [self removeLiveMap];
88-
}
89-
90-
- (BOOL)wasLiveMapPreviously
91-
{
92-
return CLLocationCoordinate2DIsValid(_centerCoordinateOfMap);
96+
ASDisplayNodeAssert(!self.isLayerBacked, @"ASMapNode can not use the interactive map feature whilst .isLayerBacked = YES, set .layerBacked = NO to use the interactive map feature.");
97+
ASDN::MutexLocker l(_propertyLock);
98+
if (liveMap == _liveMap) {
99+
return;
100+
}
101+
_liveMap = liveMap;
102+
if (self.nodeLoaded) {
103+
liveMap ? [self addLiveMap] : [self removeLiveMap];
104+
}
93105
}
94106

95107
- (BOOL)needsMapReloadOnBoundsChange
@@ -127,63 +139,62 @@ - (void)setRegion:(MKCoordinateRegion)region
127139

128140
- (void)takeSnapshot
129141
{
130-
if (!_snapshotter.isLoading) {
131-
[_snapshotter startWithCompletionHandler:^(MKMapSnapshot *snapshot, NSError *error) {
132-
if (!error) {
133-
UIImage *image = snapshot.image;
134-
CGRect finalImageRect = CGRectMake(0, 0, image.size.width, image.size.height);
135-
136-
UIGraphicsBeginImageContextWithOptions(image.size, YES, image.scale);
137-
[image drawAtPoint:CGPointMake(0, 0)];
138-
139-
if (_annotations.count > 0 ) {
140-
// Get a standard annotation view pin. Future implementations should use a custom annotation image property.
141-
MKAnnotationView *pin = [[MKPinAnnotationView alloc] initWithAnnotation:nil reuseIdentifier:@""];
142-
UIImage *pinImage = pin.image;
143-
for (id<MKAnnotation>annotation in _annotations)
142+
if (!_snapshotter) {
143+
[self setUpSnapshotter];
144+
}
145+
[_snapshotter cancel];
146+
[_snapshotter startWithCompletionHandler:^(MKMapSnapshot *snapshot, NSError *error) {
147+
if (!error) {
148+
UIImage *image = snapshot.image;
149+
CGRect finalImageRect = CGRectMake(0, 0, image.size.width, image.size.height);
150+
151+
UIGraphicsBeginImageContextWithOptions(image.size, YES, image.scale);
152+
[image drawAtPoint:CGPointMake(0, 0)];
153+
154+
if (_annotations.count > 0 ) {
155+
// Get a standard annotation view pin. Future implementations should use a custom annotation image property.
156+
MKAnnotationView *pin = [[MKPinAnnotationView alloc] initWithAnnotation:nil reuseIdentifier:@""];
157+
UIImage *pinImage = pin.image;
158+
for (id<MKAnnotation>annotation in _annotations)
159+
{
160+
CGPoint point = [snapshot pointForCoordinate:annotation.coordinate];
161+
if (CGRectContainsPoint(finalImageRect, point))
144162
{
145-
CGPoint point = [snapshot pointForCoordinate:annotation.coordinate];
146-
if (CGRectContainsPoint(finalImageRect, point))
147-
{
148-
CGPoint pinCenterOffset = pin.centerOffset;
149-
point.x -= pin.bounds.size.width / 2.0;
150-
point.y -= pin.bounds.size.height / 2.0;
151-
point.x += pinCenterOffset.x;
152-
point.y += pinCenterOffset.y;
153-
[pinImage drawAtPoint:point];
154-
}
163+
CGPoint pinCenterOffset = pin.centerOffset;
164+
point.x -= pin.bounds.size.width / 2.0;
165+
point.y -= pin.bounds.size.height / 2.0;
166+
point.x += pinCenterOffset.x;
167+
point.y += pinCenterOffset.y;
168+
[pinImage drawAtPoint:point];
155169
}
156170
}
157-
158-
UIImage *finalImage = UIGraphicsGetImageFromCurrentImageContext();
159-
UIGraphicsEndImageContext();
160-
self.image = finalImage;
161171
}
162-
}];
163-
}
172+
173+
UIImage *finalImage = UIGraphicsGetImageFromCurrentImageContext();
174+
UIGraphicsEndImageContext();
175+
self.image = finalImage;
176+
}
177+
}];
164178
}
165179

166180
- (void)setUpSnapshotter
167181
{
168-
if (!_snapshotter) {
169-
ASDisplayNodeAssert(!CGSizeEqualToSize(CGSizeZero, self.calculatedSize), @"self.calculatedSize can not be zero. Make sure that you are setting a preferredFrameSize or wrapping ASMapNode in a ASRatioLayoutSpec or similar.");
170-
_options.size = self.calculatedSize;
171-
_snapshotter = [[MKMapSnapshotter alloc] initWithOptions:_options];
172-
}
182+
ASDisplayNodeAssert(!CGSizeEqualToSize(CGSizeZero, self.calculatedSize), @"self.calculatedSize can not be zero. Make sure that you are setting a preferredFrameSize or wrapping ASMapNode in a ASRatioLayoutSpec or similar.");
183+
_options.size = self.calculatedSize;
184+
_snapshotter = [[MKMapSnapshotter alloc] initWithOptions:_options];
173185
}
174186

175187
- (void)resetSnapshotter
176188
{
177-
if (!_snapshotter.isLoading) {
178-
_snapshotter = [[MKMapSnapshotter alloc] initWithOptions:_options];
179-
}
189+
[_snapshotter cancel];
190+
_snapshotter = [[MKMapSnapshotter alloc] initWithOptions:_options];
180191
}
181192

182193
#pragma mark - Actions
183194
- (void)addLiveMap
184195
{
185196
ASDisplayNodeAssertMainThread();
186-
if (!self.isLiveMap) {
197+
if (!_mapView) {
187198
__weak ASMapNode *weakSelf = self;
188199
_mapView = [[MKMapView alloc] initWithFrame:CGRectZero];
189200
_mapView.delegate = weakSelf.mapDelegate;
@@ -194,8 +205,6 @@ - (void)addLiveMap
194205

195206
if (CLLocationCoordinate2DIsValid(_centerCoordinateOfMap)) {
196207
[_mapView setCenterCoordinate:_centerCoordinateOfMap];
197-
} else {
198-
_centerCoordinateOfMap = _options.region.center;
199208
}
200209
}
201210
}

0 commit comments

Comments
 (0)