Add ASViewController and update Multiplex sample to use it.

This commit is contained in:
Huy Nguyen
2015-09-16 22:22:08 +03:00
parent 21bdbbe12f
commit 07c0d78c71
9 changed files with 270 additions and 143 deletions

View File

@@ -10,77 +10,39 @@
*/
#import "ViewController.h"
#import "ScreenNode.h"
#import <AsyncDisplayKit/AsyncDisplayKit.h>
@interface ViewController () <ASMultiplexImageNodeDataSource, ASMultiplexImageNodeDelegate, ASImageDownloaderProtocol>
{
ASMultiplexImageNode *_imageNode;
UILabel *_textLabel;
@interface ViewController() {
ScreenNode *_screenNode;
}
@end
@implementation ViewController
- (instancetype)init
{
if (!(self = [super init]))
ScreenNode *node = [[ScreenNode alloc] init];
if (!(self = [super initWithNode:node]))
return nil;
// multiplex image node!
// NB: we're using a custom downloader with an artificial delay for this demo, but ASBasicImageDownloader works too!
_imageNode = [[ASMultiplexImageNode alloc] initWithCache:nil downloader:self];
_imageNode.dataSource = self;
_imageNode.delegate = self;
// placeholder colour
_imageNode.backgroundColor = ASDisplayNodeDefaultPlaceholderColor();
// load low-quality images before high-quality images
_imageNode.downloadsIntermediateImages = YES;
// simple status label
_textLabel = [[UILabel alloc] init];
_textLabel.textAlignment = NSTextAlignmentCenter;
_textLabel.font = [UIFont fontWithName:@"HelveticaNeue-Light" size:22.0f];
_screenNode = node;
// tap to reload
UITapGestureRecognizer *gr = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(reload:)];
[_textLabel addGestureRecognizer:gr];
[_screenNode.textNode.view addGestureRecognizer:gr];
return self;
}
- (void)viewDidLoad
- (void)viewWillAppear:(BOOL)animated
{
[super viewDidLoad];
[self.view addSubnode:_imageNode];
[self.view addSubview:_textLabel];
[self start];
[super viewWillAppear:animated];
[_screenNode start];
}
- (void)viewWillLayoutSubviews
{
static CGFloat padding = 40.0f;
// lay out image
CGFloat imageWidth = self.view.bounds.size.width - padding;
CGPoint imageOrigin = CGPointMake(roundf((self.view.bounds.size.width - imageWidth) / 2.0f),
roundf((self.view.bounds.size.height - imageWidth) / 2.0f));
_imageNode.frame = (CGRect){ imageOrigin, CGSizeMake(imageWidth, imageWidth) };
// label
CGSize textSize = [_textLabel sizeThatFits:CGSizeMake(self.view.bounds.size.width, FLT_MAX)];
_textLabel.frame = CGRectMake(0.0f, imageOrigin.y + imageWidth + padding, self.view.bounds.size.width, textSize.height);
- (void)reload:(id)sender {
[_screenNode reload];
}
- (BOOL)prefersStatusBarHidden
@@ -88,95 +50,4 @@
return YES;
}
- (void)start
{
_textLabel.text = @"loading…";
_textLabel.userInteractionEnabled = NO;
_imageNode.imageIdentifiers = @[ @"best", @"medium", @"worst" ]; // go!
}
- (void)reload:(id)sender {
[self start];
[_imageNode reloadImageIdentifierSources];
}
#pragma mark -
#pragma mark ASMultiplexImageNode data source & delegate.
- (NSURL *)multiplexImageNode:(ASMultiplexImageNode *)imageNode URLForImageIdentifier:(id)imageIdentifier
{
if ([imageIdentifier isEqualToString:@"worst"]) {
return [NSURL URLWithString:@"https://raw.githubusercontent.com/facebook/AsyncDisplayKit/master/examples/Multiplex/worst.png"];
}
if ([imageIdentifier isEqualToString:@"medium"]) {
return [NSURL URLWithString:@"https://raw.githubusercontent.com/facebook/AsyncDisplayKit/master/examples/Multiplex/medium.png"];
}
if ([imageIdentifier isEqualToString:@"best"]) {
return [NSURL URLWithString:@"https://raw.githubusercontent.com/facebook/AsyncDisplayKit/master/examples/Multiplex/best.png"];
}
// unexpected identifier
return nil;
}
- (void)multiplexImageNode:(ASMultiplexImageNode *)imageNode didFinishDownloadingImageWithIdentifier:(id)imageIdentifier error:(NSError *)error
{
_textLabel.text = [NSString stringWithFormat:@"loaded '%@'", imageIdentifier];
if ([imageIdentifier isEqualToString:@"best"]) {
_textLabel.text = [_textLabel.text stringByAppendingString:@". tap to reload"];
_textLabel.userInteractionEnabled = YES;
}
}
#pragma mark -
#pragma mark ASImageDownloaderProtocol.
- (id)downloadImageWithURL:(NSURL *)URL
callbackQueue:(dispatch_queue_t)callbackQueue
downloadProgressBlock:(void (^)(CGFloat progress))downloadProgressBlock
completion:(void (^)(CGImageRef image, NSError *error))completion
{
// if no callback queue is supplied, run on the main thread
if (callbackQueue == nil) {
callbackQueue = dispatch_get_main_queue();
}
// call completion blocks
void (^handler)(NSURLResponse *, NSData *, NSError *) = ^(NSURLResponse *response, NSData *data, NSError *connectionError) {
// add an artificial delay
usleep(1.0 * USEC_PER_SEC);
// ASMultiplexImageNode callbacks
dispatch_async(callbackQueue, ^{
if (downloadProgressBlock) {
downloadProgressBlock(1.0f);
}
if (completion) {
completion([[UIImage imageWithData:data] CGImage], connectionError);
}
});
};
// let NSURLConnection do the heavy lifting
NSURLRequest *request = [NSURLRequest requestWithURL:URL];
[NSURLConnection sendAsynchronousRequest:request
queue:[[NSOperationQueue alloc] init]
completionHandler:handler];
// return nil, don't support cancellation
return nil;
}
- (void)cancelImageDownloadForIdentifier:(id)downloadIdentifier
{
// no-op, don't support cancellation
}
@end