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

Commit 42efde3

Browse files
committed
Merge branch 'master' into ASVideoNode
2 parents 9b4226d + ca11efb commit 42efde3

13 files changed

Lines changed: 205 additions & 78 deletions

AsyncDisplayKit-Prefix.gcda

0 Bytes
Binary file not shown.

AsyncDisplayKit.xcodeproj/project.pbxproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -526,7 +526,7 @@
526526
057D02C51AC0A66700C7AC3C /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = "<group>"; };
527527
057D02C61AC0A66700C7AC3C /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = "<group>"; };
528528
0587F9BB1A7309ED00AFF0BA /* ASEditableTextNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASEditableTextNode.h; sourceTree = "<group>"; };
529-
0587F9BC1A7309ED00AFF0BA /* ASEditableTextNode.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; lineEnding = 0; path = ASEditableTextNode.mm; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
529+
0587F9BC1A7309ED00AFF0BA /* ASEditableTextNode.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; lineEnding = 0; path = ASEditableTextNode.mm; sourceTree = "<group>"; };
530530
058D09AC195D04C000B7D73C /* libAsyncDisplayKit.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libAsyncDisplayKit.a; sourceTree = BUILT_PRODUCTS_DIR; };
531531
058D09AF195D04C000B7D73C /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
532532
058D09B3195D04C000B7D73C /* AsyncDisplayKit-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "AsyncDisplayKit-Prefix.pch"; sourceTree = "<group>"; };

AsyncDisplayKit/ASDisplayNode.mm

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1816,8 +1816,28 @@ - (void)layout
18161816
CGRect subnodeFrame = CGRectZero;
18171817
for (ASLayout *subnodeLayout in _layout.sublayouts) {
18181818
ASDisplayNodeAssert([_subnodes containsObject:subnodeLayout.layoutableObject], @"Cached sublayouts must only contain subnodes' layout.");
1819-
subnodeFrame.origin = subnodeLayout.position;
1820-
subnodeFrame.size = subnodeLayout.size;
1819+
CGPoint adjustedOrigin = subnodeLayout.position;
1820+
if (isfinite(adjustedOrigin.x) == NO) {
1821+
ASDisplayNodeAssert(0, @"subnodeLayout has an invalid position");
1822+
adjustedOrigin.x = 0;
1823+
}
1824+
if (isfinite(adjustedOrigin.y) == NO) {
1825+
ASDisplayNodeAssert(0, @"subnodeLayout has an invalid position");
1826+
adjustedOrigin.y = 0;
1827+
}
1828+
subnodeFrame.origin = adjustedOrigin;
1829+
1830+
CGSize adjustedSize = subnodeLayout.size;
1831+
if (isfinite(adjustedSize.width) == NO) {
1832+
ASDisplayNodeAssert(0, @"subnodeLayout has an invalid size");
1833+
adjustedSize.width = 0;
1834+
}
1835+
if (isfinite(adjustedSize.height) == NO) {
1836+
ASDisplayNodeAssert(0, @"subnodeLayout has an invalid position");
1837+
adjustedSize.height = 0;
1838+
}
1839+
subnodeFrame.size = adjustedSize;
1840+
18211841
subnode = ((ASDisplayNode *)subnodeLayout.layoutableObject);
18221842
[subnode setFrame:subnodeFrame];
18231843
}

AsyncDisplayKit/ASMapNode.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,10 @@
1111

1212
@interface ASMapNode : ASImageNode
1313

14-
- (instancetype)initWithCoordinate:(CLLocationCoordinate2D)coordinate NS_DESIGNATED_INITIALIZER;
14+
/**
15+
The current region of ASMapNode. This can be set at any time and ASMapNode will animate the change.
16+
*/
17+
@property (nonatomic, assign) MKCoordinateRegion region;
1518

1619
/**
1720
This is the MKMapView that is the live map part of ASMapNode. This will be nil if .liveMap = NO. Note, MKMapView is *not* thread-safe.

AsyncDisplayKit/ASMapNode.mm

Lines changed: 92 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -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

AsyncDisplayKit/ASTextNode.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,9 @@ typedef NS_ENUM(NSUInteger, ASTextNodeHighlightStyle) {
194194

195195
/**
196196
@abstract Responds to actions from links in the text node.
197+
@discussion The delegate must be set before the node is loaded, and implement
198+
textNode:longPressedLinkAttribute:value:atPoint:textRange: in order for
199+
the long press gesture recognizer to be installed.
197200
*/
198201
@property (nonatomic, weak) id<ASTextNodeDelegate> delegate;
199202

@@ -233,6 +236,8 @@ typedef NS_ENUM(NSUInteger, ASTextNodeHighlightStyle) {
233236
@param value The value of the tapped attribute.
234237
@param point The point within textNode, in textNode's coordinate system, that was tapped.
235238
@param textRange The range of highlighted text.
239+
@discussion In addition to implementing this method, the delegate must be set on the text
240+
node before it is loaded (the recognizer is created in -didLoad)
236241
*/
237242
- (void)textNode:(ASTextNode *)textNode longPressedLinkAttribute:(NSString *)attribute value:(id)value atPoint:(CGPoint)point textRange:(NSRange)textRange;
238243

0 commit comments

Comments
 (0)