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

Commit f8e43ea

Browse files
committed
Merge pull request #660 from nguyenhuy/ASViewController
Add ASViewController
2 parents 21bdbbe + a864341 commit f8e43ea

9 files changed

Lines changed: 269 additions & 143 deletions

File tree

AsyncDisplayKit.xcodeproj/project.pbxproj

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,8 @@
230230
AC47D9451B3BB41900AAEE9D /* ASRelativeSize.h in Headers */ = {isa = PBXBuildFile; fileRef = AC47D9431B3BB41900AAEE9D /* ASRelativeSize.h */; settings = {ATTRIBUTES = (Public, ); }; };
231231
AC47D9461B3BB41900AAEE9D /* ASRelativeSize.mm in Sources */ = {isa = PBXBuildFile; fileRef = AC47D9441B3BB41900AAEE9D /* ASRelativeSize.mm */; };
232232
AC6456091B0A335000CF11B8 /* ASCellNode.m in Sources */ = {isa = PBXBuildFile; fileRef = AC6456071B0A335000CF11B8 /* ASCellNode.m */; };
233+
ACC945A91BA9E7A0005E1FB8 /* ASViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = ACC945A81BA9E7A0005E1FB8 /* ASViewController.h */; settings = {ATTRIBUTES = (Public, ); }; };
234+
ACC945AB1BA9E7C1005E1FB8 /* ASViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = ACC945AA1BA9E7C1005E1FB8 /* ASViewController.m */; };
233235
ACF6ED1A1B17843500DA7C62 /* ASBackgroundLayoutSpec.h in Headers */ = {isa = PBXBuildFile; fileRef = ACF6ED011B17843500DA7C62 /* ASBackgroundLayoutSpec.h */; settings = {ATTRIBUTES = (Public, ); }; };
234236
ACF6ED1B1B17843500DA7C62 /* ASBackgroundLayoutSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = ACF6ED021B17843500DA7C62 /* ASBackgroundLayoutSpec.mm */; };
235237
ACF6ED1C1B17843500DA7C62 /* ASCenterLayoutSpec.h in Headers */ = {isa = PBXBuildFile; fileRef = ACF6ED031B17843500DA7C62 /* ASCenterLayoutSpec.h */; settings = {ATTRIBUTES = (Public, ); }; };
@@ -574,6 +576,8 @@
574576
AC47D9431B3BB41900AAEE9D /* ASRelativeSize.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ASRelativeSize.h; path = AsyncDisplayKit/Layout/ASRelativeSize.h; sourceTree = "<group>"; };
575577
AC47D9441B3BB41900AAEE9D /* ASRelativeSize.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = ASRelativeSize.mm; path = AsyncDisplayKit/Layout/ASRelativeSize.mm; sourceTree = "<group>"; };
576578
AC6456071B0A335000CF11B8 /* ASCellNode.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASCellNode.m; sourceTree = "<group>"; };
579+
ACC945A81BA9E7A0005E1FB8 /* ASViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASViewController.h; sourceTree = "<group>"; };
580+
ACC945AA1BA9E7C1005E1FB8 /* ASViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASViewController.m; sourceTree = "<group>"; };
577581
ACF6ED011B17843500DA7C62 /* ASBackgroundLayoutSpec.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ASBackgroundLayoutSpec.h; path = AsyncDisplayKit/Layout/ASBackgroundLayoutSpec.h; sourceTree = "<group>"; };
578582
ACF6ED021B17843500DA7C62 /* ASBackgroundLayoutSpec.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; lineEnding = 0; name = ASBackgroundLayoutSpec.mm; path = AsyncDisplayKit/Layout/ASBackgroundLayoutSpec.mm; sourceTree = "<group>"; };
579583
ACF6ED031B17843500DA7C62 /* ASCenterLayoutSpec.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ASCenterLayoutSpec.h; path = AsyncDisplayKit/Layout/ASCenterLayoutSpec.h; sourceTree = "<group>"; };
@@ -758,6 +762,8 @@
758762
0574D5E119C110610097DC25 /* ASTableViewProtocols.h */,
759763
058D09DF195D050800B7D73C /* ASTextNode.h */,
760764
058D09E0195D050800B7D73C /* ASTextNode.mm */,
765+
ACC945A81BA9E7A0005E1FB8 /* ASViewController.h */,
766+
ACC945AA1BA9E7C1005E1FB8 /* ASViewController.m */,
761767
6BDC61F51978FEA400E50D21 /* AsyncDisplayKit.h */,
762768
058D09E1195D050800B7D73C /* Details */,
763769
058D0A01195D050800B7D73C /* Private */,
@@ -1114,6 +1120,7 @@
11141120
058D0A63195D05DC00B7D73C /* ASTextNodeTypes.h in Headers */,
11151121
058D0A64195D05DC00B7D73C /* ASTextNodeWordKerner.h in Headers */,
11161122
058D0A81195D05F900B7D73C /* ASThread.h in Headers */,
1123+
ACC945A91BA9E7A0005E1FB8 /* ASViewController.h in Headers */,
11171124
6BDC61F61979037800E50D21 /* AsyncDisplayKit.h in Headers */,
11181125
205F0E211B376416007741D0 /* CGRect+ASConvenience.h in Headers */,
11191126
058D0A66195D05DC00B7D73C /* NSMutableAttributedString+TextKitAdditions.h in Headers */,
@@ -1478,6 +1485,7 @@
14781485
058D0A1E195D050800B7D73C /* ASTextNodeShadower.m in Sources */,
14791486
058D0A1F195D050800B7D73C /* ASTextNodeTextKitHelpers.mm in Sources */,
14801487
058D0A20195D050800B7D73C /* ASTextNodeWordKerner.m in Sources */,
1488+
ACC945AB1BA9E7C1005E1FB8 /* ASViewController.m in Sources */,
14811489
205F0E221B376416007741D0 /* CGRect+ASConvenience.m in Sources */,
14821490
058D0A21195D050800B7D73C /* NSMutableAttributedString+TextKitAdditions.m in Sources */,
14831491
205F0E101B371875007741D0 /* UICollectionViewLayout+ASConvenience.m in Sources */,

AsyncDisplayKit/ASViewController.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
//
2+
// ASViewController.h
3+
// AsyncDisplayKit
4+
//
5+
// Created by Huy Nguyen on 16/09/15.
6+
// Copyright (c) 2015 Facebook. All rights reserved.
7+
//
8+
9+
#import <UIKit/UIKit.h>
10+
#import <AsyncDisplayKit/ASDisplayNode.h>
11+
12+
@interface ASViewController : UIViewController
13+
14+
@property (nonatomic, strong, readonly) ASDisplayNode *node;
15+
16+
//TODO Use nonnull annotation late on. Travis doesn't recognize it (yet).
17+
- (instancetype)initWithNode:(ASDisplayNode *)node;
18+
19+
@end

AsyncDisplayKit/ASViewController.m

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
//
2+
// ASViewController.m
3+
// AsyncDisplayKit
4+
//
5+
// Created by Huy Nguyen on 16/09/15.
6+
// Copyright (c) 2015 Facebook. All rights reserved.
7+
//
8+
9+
#import "ASViewController.h"
10+
#import "ASAssert.h"
11+
#import "ASDimension.h"
12+
13+
@implementation ASViewController
14+
15+
- (instancetype)initWithNode:(ASDisplayNode *)node
16+
{
17+
if (!(self = [super init])) {
18+
return nil;
19+
}
20+
21+
ASDisplayNodeAssertNotNil(node, @"Node must not be nil");
22+
ASDisplayNodeAssertTrue(!node.layerBacked);
23+
_node = node;
24+
25+
return self;
26+
}
27+
28+
- (void)loadView
29+
{
30+
ASDisplayNodeAssertTrue(!_node.layerBacked);
31+
self.view = _node.view;
32+
}
33+
34+
- (void)viewWillLayoutSubviews
35+
{
36+
CGSize viewSize = self.view.bounds.size;
37+
ASSizeRange constrainedSize = ASSizeRangeMake(viewSize, viewSize);
38+
[_node measureWithSizeRange:constrainedSize];
39+
[super viewWillLayoutSubviews];
40+
}
41+
42+
- (void)viewWillAppear:(BOOL)animated
43+
{
44+
[super viewWillAppear:animated];
45+
[_node recursivelyFetchData];
46+
}
47+
48+
@end

AsyncDisplayKit/AsyncDisplayKit.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@
2626

2727
#import <AsyncDisplayKit/ASScrollNode.h>
2828

29+
#import <AsyncDisplayKit/ASViewController.h>
30+
2931
#import <AsyncDisplayKit/ASLayout.h>
3032
#import <AsyncDisplayKit/ASDimension.h>
3133
#import <AsyncDisplayKit/ASLayoutable.h>

examples/Multiplex/Sample.xcodeproj/project.pbxproj

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
3EC0CDCBA10D483D9F386E5E /* libPods.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3D24B17D1E4A4E7A9566C5E9 /* libPods.a */; };
1515
6C2C82AC19EE274300767484 /* Default-667h@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 6C2C82AA19EE274300767484 /* Default-667h@2x.png */; };
1616
6C2C82AD19EE274300767484 /* Default-736h@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 6C2C82AB19EE274300767484 /* Default-736h@3x.png */; };
17+
ACC945AE1BA9EFBA005E1FB8 /* ScreenNode.m in Sources */ = {isa = PBXBuildFile; fileRef = ACC945AD1BA9EFBA005E1FB8 /* ScreenNode.m */; };
1718
/* End PBXBuildFile section */
1819

1920
/* Begin PBXFileReference section */
@@ -29,6 +30,8 @@
2930
3D24B17D1E4A4E7A9566C5E9 /* libPods.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libPods.a; sourceTree = BUILT_PRODUCTS_DIR; };
3031
6C2C82AA19EE274300767484 /* Default-667h@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-667h@2x.png"; sourceTree = SOURCE_ROOT; };
3132
6C2C82AB19EE274300767484 /* Default-736h@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-736h@3x.png"; sourceTree = SOURCE_ROOT; };
33+
ACC945AC1BA9EFB3005E1FB8 /* ScreenNode.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ScreenNode.h; sourceTree = "<group>"; };
34+
ACC945AD1BA9EFBA005E1FB8 /* ScreenNode.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ScreenNode.m; sourceTree = "<group>"; };
3235
C068F1D3F0CC317E895FCDAB /* Pods.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = Pods.debug.xcconfig; path = "Pods/Target Support Files/Pods/Pods.debug.xcconfig"; sourceTree = "<group>"; };
3336
/* End PBXFileReference section */
3437

@@ -72,6 +75,8 @@
7275
05E2128919D4DB510098F589 /* AppDelegate.m */,
7376
05E2128B19D4DB510098F589 /* ViewController.h */,
7477
05E2128C19D4DB510098F589 /* ViewController.m */,
78+
ACC945AC1BA9EFB3005E1FB8 /* ScreenNode.h */,
79+
ACC945AD1BA9EFBA005E1FB8 /* ScreenNode.m */,
7580
05E2128419D4DB510098F589 /* Supporting Files */,
7681
);
7782
path = Sample;
@@ -214,6 +219,7 @@
214219
05E2128D19D4DB510098F589 /* ViewController.m in Sources */,
215220
05E2128A19D4DB510098F589 /* AppDelegate.m in Sources */,
216221
05E2128719D4DB510098F589 /* main.m in Sources */,
222+
ACC945AE1BA9EFBA005E1FB8 /* ScreenNode.m in Sources */,
217223
);
218224
runOnlyForDeploymentPostprocessing = 0;
219225
};
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
//
2+
// ScreenNode.h
3+
// Sample
4+
//
5+
// Created by Huy Nguyen on 16/09/15.
6+
// Copyright (c) 2015 Facebook. All rights reserved.
7+
//
8+
9+
#import <AsyncDisplayKit/AsyncDisplayKit.h>
10+
11+
@interface ScreenNode : ASDisplayNode
12+
13+
@property (nonatomic, strong) ASMultiplexImageNode *imageNode;
14+
@property (nonatomic, strong) ASTextNode *textNode;
15+
16+
- (void)start;
17+
- (void)reload;
18+
19+
@end
Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
//
2+
// ScreenNode.m
3+
// Sample
4+
//
5+
// Created by Huy Nguyen on 16/09/15.
6+
// Copyright (c) 2015 Facebook. All rights reserved.
7+
//
8+
9+
#import "ScreenNode.h"
10+
11+
@interface ScreenNode() <ASMultiplexImageNodeDataSource, ASMultiplexImageNodeDelegate, ASImageDownloaderProtocol>
12+
@end
13+
14+
@implementation ScreenNode
15+
16+
- (instancetype)init
17+
{
18+
if (!(self = [super init])) {
19+
return nil;
20+
}
21+
22+
// multiplex image node!
23+
// NB: we're using a custom downloader with an artificial delay for this demo, but ASBasicImageDownloader works too!
24+
_imageNode = [[ASMultiplexImageNode alloc] initWithCache:nil downloader:self];
25+
_imageNode.dataSource = self;
26+
_imageNode.delegate = self;
27+
28+
// placeholder colour
29+
_imageNode.backgroundColor = ASDisplayNodeDefaultPlaceholderColor();
30+
31+
// load low-quality images before high-quality images
32+
_imageNode.downloadsIntermediateImages = YES;
33+
34+
// simple status label
35+
_textNode = [[ASTextNode alloc] init];
36+
37+
[self addSubnode:_imageNode];
38+
[self addSubnode:_textNode];
39+
40+
return self;
41+
}
42+
43+
- (void)start
44+
{
45+
[self setText:@"loading…"];
46+
_textNode.userInteractionEnabled = NO;
47+
_imageNode.imageIdentifiers = @[ @"best", @"medium", @"worst" ]; // go!
48+
}
49+
50+
- (void)reload {
51+
[self start];
52+
[_imageNode reloadImageIdentifierSources];
53+
}
54+
55+
- (void)setText:(NSString *)text
56+
{
57+
NSDictionary *attributes = @{NSFontAttributeName: [UIFont fontWithName:@"HelveticaNeue-Light" size:22.0f]};
58+
NSAttributedString *string = [[NSAttributedString alloc] initWithString:text
59+
attributes:attributes];
60+
_textNode.attributedString = string;
61+
[self setNeedsLayout];
62+
}
63+
64+
- (ASLayoutSpec *)layoutSpecThatFits:(ASSizeRange)constrainedSize
65+
{
66+
ASRatioLayoutSpec *imagePlaceholder = [ASRatioLayoutSpec ratioLayoutSpecWithRatio:1 child:_imageNode];
67+
ASStackLayoutSpec *verticalStack = [ASStackLayoutSpec stackLayoutSpecWithDirection:ASStackLayoutDirectionVertical
68+
spacing:10
69+
justifyContent:ASStackLayoutJustifyContentCenter
70+
alignItems:ASStackLayoutAlignItemsCenter
71+
children:@[imagePlaceholder, _textNode]];
72+
return [ASInsetLayoutSpec insetLayoutSpecWithInsets:UIEdgeInsetsMake(10, 10, 10, 10) child:verticalStack];
73+
}
74+
75+
#pragma mark -
76+
#pragma mark ASMultiplexImageNode data source & delegate.
77+
78+
- (NSURL *)multiplexImageNode:(ASMultiplexImageNode *)imageNode URLForImageIdentifier:(id)imageIdentifier
79+
{
80+
if ([imageIdentifier isEqualToString:@"worst"]) {
81+
return [NSURL URLWithString:@"https://raw.githubusercontent.com/facebook/AsyncDisplayKit/master/examples/Multiplex/worst.png"];
82+
}
83+
84+
if ([imageIdentifier isEqualToString:@"medium"]) {
85+
return [NSURL URLWithString:@"https://raw.githubusercontent.com/facebook/AsyncDisplayKit/master/examples/Multiplex/medium.png"];
86+
}
87+
88+
if ([imageIdentifier isEqualToString:@"best"]) {
89+
return [NSURL URLWithString:@"https://raw.githubusercontent.com/facebook/AsyncDisplayKit/master/examples/Multiplex/best.png"];
90+
}
91+
92+
// unexpected identifier
93+
return nil;
94+
}
95+
96+
- (void)multiplexImageNode:(ASMultiplexImageNode *)imageNode didFinishDownloadingImageWithIdentifier:(id)imageIdentifier error:(NSError *)error
97+
{
98+
[self setText:[NSString stringWithFormat:@"loaded '%@'", imageIdentifier]];
99+
100+
if ([imageIdentifier isEqualToString:@"best"]) {
101+
[self setText:[_textNode.attributedString.string stringByAppendingString:@". tap to reload"]];
102+
_textNode.userInteractionEnabled = YES;
103+
}
104+
}
105+
106+
107+
#pragma mark -
108+
#pragma mark ASImageDownloaderProtocol.
109+
110+
- (id)downloadImageWithURL:(NSURL *)URL
111+
callbackQueue:(dispatch_queue_t)callbackQueue
112+
downloadProgressBlock:(void (^)(CGFloat progress))downloadProgressBlock
113+
completion:(void (^)(CGImageRef image, NSError *error))completion
114+
{
115+
// if no callback queue is supplied, run on the main thread
116+
if (callbackQueue == nil) {
117+
callbackQueue = dispatch_get_main_queue();
118+
}
119+
120+
// call completion blocks
121+
void (^handler)(NSURLResponse *, NSData *, NSError *) = ^(NSURLResponse *response, NSData *data, NSError *connectionError) {
122+
// add an artificial delay
123+
usleep(1.0 * USEC_PER_SEC);
124+
125+
// ASMultiplexImageNode callbacks
126+
dispatch_async(callbackQueue, ^{
127+
if (downloadProgressBlock) {
128+
downloadProgressBlock(1.0f);
129+
}
130+
131+
if (completion) {
132+
completion([[UIImage imageWithData:data] CGImage], connectionError);
133+
}
134+
});
135+
};
136+
137+
// let NSURLConnection do the heavy lifting
138+
NSURLRequest *request = [NSURLRequest requestWithURL:URL];
139+
[NSURLConnection sendAsynchronousRequest:request
140+
queue:[[NSOperationQueue alloc] init]
141+
completionHandler:handler];
142+
143+
// return nil, don't support cancellation
144+
return nil;
145+
}
146+
147+
- (void)cancelImageDownloadForIdentifier:(id)downloadIdentifier
148+
{
149+
// no-op, don't support cancellation
150+
}
151+
152+
@end

examples/Multiplex/Sample/ViewController.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@
99
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
1010
*/
1111

12-
#import <UIKit/UIKit.h>
12+
#import <AsyncDisplayKit/ASViewController.h>
1313

14-
@interface ViewController : UIViewController
14+
@interface ViewController : ASViewController
1515

1616
@end

0 commit comments

Comments
 (0)