@@ -17,70 +17,80 @@ @interface ASMapNode()
1717 MKMapSnapshotter *_snapshotter;
1818 MKMapSnapshotOptions *_options;
1919 NSArray *_annotations;
20- ASDisplayNode *_mapNode;
2120 CLLocationCoordinate2D _centerCoordinateOfMap;
2221}
2322@end
2423
2524@implementation ASMapNode
2625
27- @synthesize liveMap = _liveMap;
2826@synthesize needsMapReloadOnBoundsChange = _needsMapReloadOnBoundsChange;
2927@synthesize mapDelegate = _mapDelegate;
28+ @synthesize region = _region;
3029
31- - (instancetype )initWithCoordinate : (CLLocationCoordinate2D)coordinate
30+ #pragma mark - Lifecycle
31+ - (instancetype )init
3232{
3333 if (!(self = [super init ])) {
3434 return nil ;
3535 }
3636 self.backgroundColor = ASDisplayNodeDefaultPlaceholderColor ();
3737 self.clipsToBounds = YES ;
38-
38+
3939 _needsMapReloadOnBoundsChange = YES ;
40- _liveMap = NO ;
40+
4141 _centerCoordinateOfMap = kCLLocationCoordinate2DInvalid ;
42-
42+ _region = MKCoordinateRegionMake (CLLocationCoordinate2DMake (43.432858 , 13.183671 ), MKCoordinateSpanMake (0.2 , 0.2 ));
43+
4344 _options = [[MKMapSnapshotOptions alloc ] init ];
44- _options.region = MKCoordinateRegionMakeWithDistance (coordinate, 1000 , 1000 ); ;
45+ _options.region = _region ;
4546
4647 return self;
4748}
4849
49- - (void )setAnnotations : ( NSArray *) annotations
50+ - (void )didLoad
5051{
51- ASDN::MutexLocker l (_propertyLock);
52- _annotations = [annotations copy ];
53- if (annotations.count != _annotations.count ) {
54- // Redraw
55- [self setNeedsDisplay ];
52+ [super didLoad ];
53+ if ([self wasLiveMapPreviously ]) {
54+ self.userInteractionEnabled = YES ;
55+ [self addLiveMap ];
5656 }
5757}
5858
59- - (void )setUpSnapshotter
59+ - (void )fetchData
6060{
61- if (!_snapshotter) {
62- 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." );
63- _options.size = self.calculatedSize ;
64- _snapshotter = [[MKMapSnapshotter alloc ] initWithOptions: _options];
61+ [super fetchData ];
62+ if ([self wasLiveMapPreviously ]) {
63+ [self addLiveMap ];
64+ } else {
65+ [self setUpSnapshotter ];
66+ [self takeSnapshot ];
6567 }
6668}
6769
70+ - (void )clearFetchedData
71+ {
72+ [super clearFetchedData ];
73+ if (self.isLiveMap ) {
74+ [self removeLiveMap ];
75+ }
76+ }
77+
78+ #pragma mark - Settings
79+
6880- (BOOL )isLiveMap
6981{
70- ASDN::MutexLocker l (_propertyLock);
71- return _liveMap;
82+ return (_mapView != nil );
7283}
7384
7485- (void )setLiveMap : (BOOL )liveMap
7586{
76- ASDN::MutexLocker l (_propertyLock);
77- if (liveMap == _liveMap) {
78- return ;
79- }
80- _liveMap = liveMap;
8187 liveMap ? [self addLiveMap ] : [self removeLiveMap ];
8288}
8389
90+ - (BOOL )wasLiveMapPreviously
91+ {
92+ return CLLocationCoordinate2DIsValid (_centerCoordinateOfMap);
93+ }
8494
8595- (BOOL )needsMapReloadOnBoundsChange
8696{
@@ -94,24 +104,27 @@ - (void)setNeedsMapReloadOnBoundsChange:(BOOL)needsMapReloadOnBoundsChange
94104 _needsMapReloadOnBoundsChange = needsMapReloadOnBoundsChange;
95105}
96106
97- - (void ) fetchData
107+ - (MKCoordinateRegion) region
98108{
99- [super fetchData ];
100- if (_liveMap && !_mapNode) {
101- [self addLiveMap ];
102- }
103- else {
104- [self setUpSnapshotter ];
105- [self takeSnapshot ];
106- }
109+ ASDN::MutexLocker l (_propertyLock);
110+ return _region;
107111}
108112
109- - (void )clearFetchedData
113+ - (void )setRegion : (MKCoordinateRegion) region
110114{
111- [super clearFetchedData ];
112- [self removeLiveMap ];
115+ ASDN::MutexLocker l (_propertyLock);
116+ _region = region;
117+ if (self.isLiveMap ) {
118+ [_mapView setRegion: _region animated: YES ];
119+ } else {
120+ _options.region = _region;
121+ [self resetSnapshotter ];
122+ [self takeSnapshot ];
123+ }
113124}
114125
126+ #pragma mark - Snapshotter
127+
115128- (void )takeSnapshot
116129{
117130 if (!_snapshotter.isLoading ) {
@@ -150,61 +163,76 @@ - (void)takeSnapshot
150163 }
151164}
152165
166+ - (void )setUpSnapshotter
167+ {
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+ }
173+ }
174+
153175- (void )resetSnapshotter
154176{
155177 if (!_snapshotter.isLoading ) {
156- _options.size = self.calculatedSize ;
157178 _snapshotter = [[MKMapSnapshotter alloc ] initWithOptions: _options];
158179 }
159180}
160181
161- #pragma mark - Action
182+ #pragma mark - Actions
162183- (void )addLiveMap
163184{
164- if (self. isNodeLoaded && !_mapNode) {
165- _mapNode = [[ASDisplayNode alloc ]initWithViewBlock:^UIView * {
166- _mapView = [[MKMapView alloc ]initWithFrame: CGRectMake ( 0 . 0f , 0 . 0f , self .calculatedSize.width, self .calculatedSize.height)] ;
167- _mapView. delegate = _mapDelegate ;
168- [ _mapView setRegion: _options.region] ;
169- [_mapView addAnnotations: _annotations ];
170- return _mapView;
171- } ];
172- [self addSubnode: _mapNode ];
185+ ASDisplayNodeAssertMainThread ();
186+ if (!self. isLiveMap ) {
187+ __weak ASMapNode *weakSelf = self;
188+ _mapView = [[MKMapView alloc ] initWithFrame: CGRectZero] ;
189+ _mapView. delegate = weakSelf. mapDelegate ;
190+ [_mapView setRegion: _options.region ];
191+ [ _mapView addAnnotations: _annotations] ;
192+ [weakSelf setNeedsLayout ];
193+ [weakSelf.view addSubview: _mapView ];
173194
174195 if (CLLocationCoordinate2DIsValid (_centerCoordinateOfMap)) {
175196 [_mapView setCenterCoordinate: _centerCoordinateOfMap];
197+ } else {
198+ _centerCoordinateOfMap = _options.region .center ;
176199 }
177200 }
178201}
179202
180203- (void )removeLiveMap
181204{
182- if (_mapNode) {
183- _centerCoordinateOfMap = _mapView.centerCoordinate ;
184- [_mapNode removeFromSupernode ];
185- _mapView = nil ;
186- _mapNode = nil ;
205+ _centerCoordinateOfMap = _mapView.centerCoordinate ;
206+ [_mapView removeFromSuperview ];
207+ _mapView = nil ;
208+ }
209+
210+ - (void )setAnnotations : (NSArray *)annotations
211+ {
212+ ASDN::MutexLocker l (_propertyLock);
213+ _annotations = [annotations copy ];
214+ if (self.isLiveMap ) {
215+ [_mapView removeAnnotations: _mapView.annotations];
216+ [_mapView addAnnotations: annotations];
217+ } else {
218+ [self takeSnapshot ];
187219 }
188- self.image = nil ;
189220}
190221
191222#pragma mark - Layout
192223// Layout isn't usually needed in the box model, but since we are making use of MKMapView which is hidden in an ASDisplayNode this is preferred.
193224- (void )layout
194225{
195226 [super layout ];
196- if (_mapView ) {
227+ if (self. isLiveMap ) {
197228 _mapView.frame = CGRectMake (0 .0f , 0 .0f , self.calculatedSize .width , self.calculatedSize .height );
198- }
199- else {
229+ } else {
200230 // If our bounds.size is different from our current snapshot size, then let's request a new image from MKMapSnapshotter.
201- if (!CGSizeEqualToSize (_options.size , self.bounds .size )) {
202- if (_needsMapReloadOnBoundsChange && self.image ) {
203- [self resetSnapshotter ];
204- [self takeSnapshot ];
205- }
231+ if (!CGSizeEqualToSize (_options.size , self.bounds .size ) && _needsMapReloadOnBoundsChange) {
232+ _options.size = self.bounds .size ;
233+ [self resetSnapshotter ];
234+ [self takeSnapshot ];
206235 }
207236 }
208237}
209-
210- @end
238+ @end
0 commit comments