diff --git a/AsyncDisplayKit/ASMapNode.h b/AsyncDisplayKit/ASMapNode.h index 566e6dc0f3..4b5ca85873 100644 --- a/AsyncDisplayKit/ASMapNode.h +++ b/AsyncDisplayKit/ASMapNode.h @@ -5,6 +5,7 @@ * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. */ + #import #import @interface ASMapNode : ASControlNode diff --git a/AsyncDisplayKit/ASMapNode.mm b/AsyncDisplayKit/ASMapNode.mm index 869cf0ccfa..fdf1067f49 100644 --- a/AsyncDisplayKit/ASMapNode.mm +++ b/AsyncDisplayKit/ASMapNode.mm @@ -13,12 +13,12 @@ @interface ASMapNode() { - ASDN::RecursiveMutex _propertyLock; - CGSize _nodeSize; - MKMapSnapshotter *_snapshotter; - MKMapSnapshotOptions *_options; - CGSize _maxSize; - NSArray *_annotations; + ASDN::RecursiveMutex _propertyLock; + CGSize _nodeSize; + MKMapSnapshotter *_snapshotter; + MKMapSnapshotOptions *_options; + CGSize _maxSize; + NSArray *_annotations; } @end @@ -34,202 +34,202 @@ if (!(self = [super init])) { return nil; } - self.backgroundColor = ASDisplayNodeDefaultPlaceholderColor(); - _hasLiveMap = YES; - _automaticallyReloadsMapImageOnOrientationChange = YES; - _options = [[MKMapSnapshotOptions alloc] init]; - _options.region = MKCoordinateRegionMakeWithDistance(coordinate, 1000, 1000);; - - _mapImage = [[ASImageNode alloc]init]; - _mapImage.clipsToBounds = YES; - [self addSubnode:_mapImage]; - [self updateGesture]; - _maxSize = self.bounds.size; - return self; + self.backgroundColor = ASDisplayNodeDefaultPlaceholderColor(); + _hasLiveMap = YES; + _automaticallyReloadsMapImageOnOrientationChange = YES; + _options = [[MKMapSnapshotOptions alloc] init]; + _options.region = MKCoordinateRegionMakeWithDistance(coordinate, 1000, 1000);; + + _mapImage = [[ASImageNode alloc]init]; + _mapImage.clipsToBounds = YES; + [self addSubnode:_mapImage]; + [self updateGesture]; + _maxSize = self.bounds.size; + return self; } - (void)addAnnotations:(NSArray *)annotations { - ASDN::MutexLocker l(_propertyLock); - if (annotations.count == 0) { - return; - } - _annotations = [annotations copy]; - if (annotations.count != _annotations.count && _mapImage.image) { - // Redraw - [self setNeedsDisplay]; - } + ASDN::MutexLocker l(_propertyLock); + if (annotations.count == 0) { + return; + } + _annotations = [annotations copy]; + if (annotations.count != _annotations.count && _mapImage.image) { + // Redraw + [self setNeedsDisplay]; + } } - (void)setUpSnapshotter { - if (!_snapshotter) { - _options.size = _nodeSize; - _snapshotter = [[MKMapSnapshotter alloc] initWithOptions:_options]; - } + if (!_snapshotter) { + _options.size = _nodeSize; + _snapshotter = [[MKMapSnapshotter alloc] initWithOptions:_options]; + } } - (BOOL)hasLiveMap { - ASDN::MutexLocker l(_propertyLock); - return _hasLiveMap; + ASDN::MutexLocker l(_propertyLock); + return _hasLiveMap; } - (void)setHasLiveMap:(BOOL)hasLiveMap { - ASDN::MutexLocker l(_propertyLock); - if (hasLiveMap == _hasLiveMap) - return; - - _hasLiveMap = hasLiveMap; - [self updateGesture]; + ASDN::MutexLocker l(_propertyLock); + if (hasLiveMap == _hasLiveMap) + return; + + _hasLiveMap = hasLiveMap; + [self updateGesture]; } - (CGSize)mapSize { - ASDN::MutexLocker l(_propertyLock); - return _mapSize; + ASDN::MutexLocker l(_propertyLock); + return _mapSize; } - (void)setMapSize:(CGSize)mapSize { - ASDN::MutexLocker l(_propertyLock); - if (CGSizeEqualToSize(mapSize,_mapSize)) { - return; - } - _mapSize = mapSize; - _nodeSize = _mapSize; - _automaticallyReloadsMapImageOnOrientationChange = NO; - [self setNeedsLayout]; + ASDN::MutexLocker l(_propertyLock); + if (CGSizeEqualToSize(mapSize,_mapSize)) { + return; + } + _mapSize = mapSize; + _nodeSize = _mapSize; + _automaticallyReloadsMapImageOnOrientationChange = NO; + [self setNeedsLayout]; } - (BOOL)automaticallyReloadsMapImageOnOrientationChange { - ASDN::MutexLocker l(_propertyLock); - return _automaticallyReloadsMapImageOnOrientationChange; + ASDN::MutexLocker l(_propertyLock); + return _automaticallyReloadsMapImageOnOrientationChange; } - (void)setAutomaticallyReloadsMapImageOnOrientationChange:(BOOL)automaticallyReloadsMapImageOnOrientationChange { - ASDN::MutexLocker l(_propertyLock); - if (_automaticallyReloadsMapImageOnOrientationChange == automaticallyReloadsMapImageOnOrientationChange) { - return; - } - _automaticallyReloadsMapImageOnOrientationChange = automaticallyReloadsMapImageOnOrientationChange; - + ASDN::MutexLocker l(_propertyLock); + if (_automaticallyReloadsMapImageOnOrientationChange == automaticallyReloadsMapImageOnOrientationChange) { + return; + } + _automaticallyReloadsMapImageOnOrientationChange = automaticallyReloadsMapImageOnOrientationChange; + } - (void)updateGesture { - _hasLiveMap ? [self addTarget:self action:@selector(showLiveMap) forControlEvents:ASControlNodeEventTouchUpInside] : [self removeTarget:self action:@selector(showLiveMap) forControlEvents:ASControlNodeEventTouchUpInside]; + _hasLiveMap ? [self addTarget:self action:@selector(showLiveMap) forControlEvents:ASControlNodeEventTouchUpInside] : [self removeTarget:self action:@selector(showLiveMap) forControlEvents:ASControlNodeEventTouchUpInside]; } - (void)fetchData { [super fetchData]; - [self setUpSnapshotter]; - [self takeSnapshot]; + [self setUpSnapshotter]; + [self takeSnapshot]; } - (void)clearFetchedData { - [super clearFetchedData]; - if (_liveMap) { - [_liveMap removeFromSupernode]; - _liveMap = nil; - } - _mapImage.image = nil; + [super clearFetchedData]; + if (_liveMap) { + [_liveMap removeFromSupernode]; + _liveMap = nil; + } + _mapImage.image = nil; } - (void)takeSnapshot { - if (!_snapshotter.isLoading) { - [_snapshotter startWithCompletionHandler:^(MKMapSnapshot *snapshot, NSError *error) { - if (!error) { - UIImage *image = snapshot.image; - CGRect finalImageRect = CGRectMake(0, 0, image.size.width, image.size.height); - - // Get a standard annotation view pin. Future implementations should use a custom annotation image property. - MKAnnotationView *pin = [[MKPinAnnotationView alloc] initWithAnnotation:nil reuseIdentifier:@""]; - UIImage *pinImage = pin.image; - - UIGraphicsBeginImageContextWithOptions(image.size, YES, image.scale); - [image drawAtPoint:CGPointMake(0, 0)]; - - for (idannotation in _annotations) - { - CGPoint point = [snapshot pointForCoordinate:annotation.coordinate]; - if (CGRectContainsPoint(finalImageRect, point)) - { - CGPoint pinCenterOffset = pin.centerOffset; - point.x -= pin.bounds.size.width / 2.0; - point.y -= pin.bounds.size.height / 2.0; - point.x += pinCenterOffset.x; - point.y += pinCenterOffset.y; - [pinImage drawAtPoint:point]; - } - } - UIImage *finalImage = UIGraphicsGetImageFromCurrentImageContext(); - UIGraphicsEndImageContext(); - _mapImage.image = finalImage; - } - }]; - } + if (!_snapshotter.isLoading) { + [_snapshotter startWithCompletionHandler:^(MKMapSnapshot *snapshot, NSError *error) { + if (!error) { + UIImage *image = snapshot.image; + CGRect finalImageRect = CGRectMake(0, 0, image.size.width, image.size.height); + + // Get a standard annotation view pin. Future implementations should use a custom annotation image property. + MKAnnotationView *pin = [[MKPinAnnotationView alloc] initWithAnnotation:nil reuseIdentifier:@""]; + UIImage *pinImage = pin.image; + + UIGraphicsBeginImageContextWithOptions(image.size, YES, image.scale); + [image drawAtPoint:CGPointMake(0, 0)]; + + for (idannotation in _annotations) + { + CGPoint point = [snapshot pointForCoordinate:annotation.coordinate]; + if (CGRectContainsPoint(finalImageRect, point)) + { + CGPoint pinCenterOffset = pin.centerOffset; + point.x -= pin.bounds.size.width / 2.0; + point.y -= pin.bounds.size.height / 2.0; + point.x += pinCenterOffset.x; + point.y += pinCenterOffset.y; + [pinImage drawAtPoint:point]; + } + } + UIImage *finalImage = UIGraphicsGetImageFromCurrentImageContext(); + UIGraphicsEndImageContext(); + _mapImage.image = finalImage; + } + }]; + } } - (void)resetSnapshotter { - if (!_snapshotter.isLoading) { - _options.size = _nodeSize; - _snapshotter = [[MKMapSnapshotter alloc] initWithOptions:_options]; - } + if (!_snapshotter.isLoading) { + _options.size = _nodeSize; + _snapshotter = [[MKMapSnapshotter alloc] initWithOptions:_options]; + } } #pragma mark - Action - (void)showLiveMap { - if (self.isNodeLoaded && !_liveMap) { - _liveMap = [[ASDisplayNode alloc]initWithViewBlock:^UIView *{ - MKMapView *mapView = [[MKMapView alloc]initWithFrame:CGRectMake(0.0f, 0.0f, self.calculatedSize.width, self.calculatedSize.height)]; - mapView.delegate = _mapDelegate; - [mapView setRegion:_options.region]; - [mapView addAnnotations:_annotations]; - return mapView; - }]; - [self addSubnode:_liveMap]; - _mapImage.image = nil; - } + if (self.isNodeLoaded && !_liveMap) { + _liveMap = [[ASDisplayNode alloc]initWithViewBlock:^UIView *{ + MKMapView *mapView = [[MKMapView alloc]initWithFrame:CGRectMake(0.0f, 0.0f, self.calculatedSize.width, self.calculatedSize.height)]; + mapView.delegate = _mapDelegate; + [mapView setRegion:_options.region]; + [mapView addAnnotations:_annotations]; + return mapView; + }]; + [self addSubnode:_liveMap]; + _mapImage.image = nil; + } } #pragma mark - Layout - (CGSize)calculateSizeThatFits:(CGSize)constrainedSize { - _nodeSize = CGSizeEqualToSize(CGSizeZero, _mapSize) ? CGSizeMake(constrainedSize.width, _options.size.height) : _mapSize; - if (_mapImage) { - [_mapImage calculateSizeThatFits:_nodeSize]; - } - return _nodeSize; + _nodeSize = CGSizeEqualToSize(CGSizeZero, _mapSize) ? CGSizeMake(constrainedSize.width, _options.size.height) : _mapSize; + if (_mapImage) { + [_mapImage calculateSizeThatFits:_nodeSize]; + } + return _nodeSize; } // 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. - (void)layout { - [super layout]; - if (_liveMap) { - MKMapView *mapView = (MKMapView *)_liveMap.view; - mapView.frame = CGRectMake(0.0f, 0.0f, self.calculatedSize.width, self.calculatedSize.height); - } - else { - _mapImage.frame = CGRectMake(0.0f, 0.0f, self.calculatedSize.width, self.calculatedSize.height); - if (!CGSizeEqualToSize(_maxSize, self.bounds.size)) { - _mapImage.preferredFrameSize = self.bounds.size; - _maxSize = self.bounds.size; - if (_automaticallyReloadsMapImageOnOrientationChange && _mapImage.image) { - [self resetSnapshotter]; - [self takeSnapshot]; - } - } + [super layout]; + if (_liveMap) { + MKMapView *mapView = (MKMapView *)_liveMap.view; + mapView.frame = CGRectMake(0.0f, 0.0f, self.calculatedSize.width, self.calculatedSize.height); + } + else { + _mapImage.frame = CGRectMake(0.0f, 0.0f, self.calculatedSize.width, self.calculatedSize.height); + if (!CGSizeEqualToSize(_maxSize, self.bounds.size)) { + _mapImage.preferredFrameSize = self.bounds.size; + _maxSize = self.bounds.size; + if (_automaticallyReloadsMapImageOnOrientationChange && _mapImage.image) { + [self resetSnapshotter]; + [self takeSnapshot]; + } } + } } @end