mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-24 07:05:35 +00:00
Add ASViewController and update Multiplex sample to use it.
This commit is contained in:
@@ -230,6 +230,8 @@
|
||||
AC47D9451B3BB41900AAEE9D /* ASRelativeSize.h in Headers */ = {isa = PBXBuildFile; fileRef = AC47D9431B3BB41900AAEE9D /* ASRelativeSize.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
AC47D9461B3BB41900AAEE9D /* ASRelativeSize.mm in Sources */ = {isa = PBXBuildFile; fileRef = AC47D9441B3BB41900AAEE9D /* ASRelativeSize.mm */; };
|
||||
AC6456091B0A335000CF11B8 /* ASCellNode.m in Sources */ = {isa = PBXBuildFile; fileRef = AC6456071B0A335000CF11B8 /* ASCellNode.m */; };
|
||||
ACC945A91BA9E7A0005E1FB8 /* ASViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = ACC945A81BA9E7A0005E1FB8 /* ASViewController.h */; };
|
||||
ACC945AB1BA9E7C1005E1FB8 /* ASViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = ACC945AA1BA9E7C1005E1FB8 /* ASViewController.m */; };
|
||||
ACF6ED1A1B17843500DA7C62 /* ASBackgroundLayoutSpec.h in Headers */ = {isa = PBXBuildFile; fileRef = ACF6ED011B17843500DA7C62 /* ASBackgroundLayoutSpec.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
ACF6ED1B1B17843500DA7C62 /* ASBackgroundLayoutSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = ACF6ED021B17843500DA7C62 /* ASBackgroundLayoutSpec.mm */; };
|
||||
ACF6ED1C1B17843500DA7C62 /* ASCenterLayoutSpec.h in Headers */ = {isa = PBXBuildFile; fileRef = ACF6ED031B17843500DA7C62 /* ASCenterLayoutSpec.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
@@ -574,6 +576,8 @@
|
||||
AC47D9431B3BB41900AAEE9D /* ASRelativeSize.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ASRelativeSize.h; path = AsyncDisplayKit/Layout/ASRelativeSize.h; sourceTree = "<group>"; };
|
||||
AC47D9441B3BB41900AAEE9D /* ASRelativeSize.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = ASRelativeSize.mm; path = AsyncDisplayKit/Layout/ASRelativeSize.mm; sourceTree = "<group>"; };
|
||||
AC6456071B0A335000CF11B8 /* ASCellNode.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASCellNode.m; sourceTree = "<group>"; };
|
||||
ACC945A81BA9E7A0005E1FB8 /* ASViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASViewController.h; sourceTree = "<group>"; };
|
||||
ACC945AA1BA9E7C1005E1FB8 /* ASViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASViewController.m; sourceTree = "<group>"; };
|
||||
ACF6ED011B17843500DA7C62 /* ASBackgroundLayoutSpec.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ASBackgroundLayoutSpec.h; path = AsyncDisplayKit/Layout/ASBackgroundLayoutSpec.h; sourceTree = "<group>"; };
|
||||
ACF6ED021B17843500DA7C62 /* ASBackgroundLayoutSpec.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; lineEnding = 0; name = ASBackgroundLayoutSpec.mm; path = AsyncDisplayKit/Layout/ASBackgroundLayoutSpec.mm; sourceTree = "<group>"; };
|
||||
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 @@
|
||||
0574D5E119C110610097DC25 /* ASTableViewProtocols.h */,
|
||||
058D09DF195D050800B7D73C /* ASTextNode.h */,
|
||||
058D09E0195D050800B7D73C /* ASTextNode.mm */,
|
||||
ACC945A81BA9E7A0005E1FB8 /* ASViewController.h */,
|
||||
ACC945AA1BA9E7C1005E1FB8 /* ASViewController.m */,
|
||||
6BDC61F51978FEA400E50D21 /* AsyncDisplayKit.h */,
|
||||
058D09E1195D050800B7D73C /* Details */,
|
||||
058D0A01195D050800B7D73C /* Private */,
|
||||
@@ -1114,6 +1120,7 @@
|
||||
058D0A63195D05DC00B7D73C /* ASTextNodeTypes.h in Headers */,
|
||||
058D0A64195D05DC00B7D73C /* ASTextNodeWordKerner.h in Headers */,
|
||||
058D0A81195D05F900B7D73C /* ASThread.h in Headers */,
|
||||
ACC945A91BA9E7A0005E1FB8 /* ASViewController.h in Headers */,
|
||||
6BDC61F61979037800E50D21 /* AsyncDisplayKit.h in Headers */,
|
||||
205F0E211B376416007741D0 /* CGRect+ASConvenience.h in Headers */,
|
||||
058D0A66195D05DC00B7D73C /* NSMutableAttributedString+TextKitAdditions.h in Headers */,
|
||||
@@ -1478,6 +1485,7 @@
|
||||
058D0A1E195D050800B7D73C /* ASTextNodeShadower.m in Sources */,
|
||||
058D0A1F195D050800B7D73C /* ASTextNodeTextKitHelpers.mm in Sources */,
|
||||
058D0A20195D050800B7D73C /* ASTextNodeWordKerner.m in Sources */,
|
||||
ACC945AB1BA9E7C1005E1FB8 /* ASViewController.m in Sources */,
|
||||
205F0E221B376416007741D0 /* CGRect+ASConvenience.m in Sources */,
|
||||
058D0A21195D050800B7D73C /* NSMutableAttributedString+TextKitAdditions.m in Sources */,
|
||||
205F0E101B371875007741D0 /* UICollectionViewLayout+ASConvenience.m in Sources */,
|
||||
|
||||
18
AsyncDisplayKit/ASViewController.h
Normal file
18
AsyncDisplayKit/ASViewController.h
Normal file
@@ -0,0 +1,18 @@
|
||||
//
|
||||
// ASViewController.h
|
||||
// AsyncDisplayKit
|
||||
//
|
||||
// Created by Huy Nguyen on 16/09/15.
|
||||
// Copyright (c) 2015 Facebook. All rights reserved.
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
#import <AsyncDisplayKit/AsyncDisplayKit.h>
|
||||
|
||||
@interface ASViewController : UIViewController
|
||||
|
||||
@property (nonatomic, strong, readonly) ASDisplayNode *node;
|
||||
|
||||
- (instancetype)initWithNode:(ASDisplayNode *)node;
|
||||
|
||||
@end
|
||||
47
AsyncDisplayKit/ASViewController.m
Normal file
47
AsyncDisplayKit/ASViewController.m
Normal file
@@ -0,0 +1,47 @@
|
||||
//
|
||||
// ASViewController.m
|
||||
// AsyncDisplayKit
|
||||
//
|
||||
// Created by Huy Nguyen on 16/09/15.
|
||||
// Copyright (c) 2015 Facebook. All rights reserved.
|
||||
//
|
||||
|
||||
#import "ASViewController.h"
|
||||
#import "ASAssert.h"
|
||||
#import "ASDimension.h"
|
||||
|
||||
@implementation ASViewController
|
||||
|
||||
- (instancetype)initWithNode:(ASDisplayNode *)node
|
||||
{
|
||||
if (!(self = [super init])) {
|
||||
return nil;
|
||||
}
|
||||
|
||||
ASDisplayNodeAssertNotNil(node, @"Node must not be nil");
|
||||
ASDisplayNodeAssertTrue(!node.layerBacked);
|
||||
_node = node;
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)loadView
|
||||
{
|
||||
ASDisplayNodeAssertTrue(!_node.layerBacked);
|
||||
self.view = _node.view;
|
||||
}
|
||||
|
||||
- (void)viewWillLayoutSubviews
|
||||
{
|
||||
ASSizeRange constrainedSize = ASSizeRangeMake(self.view.bounds.size, self.view.bounds.size);
|
||||
[_node measureWithSizeRange:constrainedSize];
|
||||
[super viewWillLayoutSubviews];
|
||||
}
|
||||
|
||||
- (void)viewWillAppear:(BOOL)animated
|
||||
{
|
||||
[super viewWillAppear:animated];
|
||||
[_node recursivelyFetchData];
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -26,6 +26,8 @@
|
||||
|
||||
#import <AsyncDisplayKit/ASScrollNode.h>
|
||||
|
||||
#import <AsyncDisplayKit/ASViewController.h>
|
||||
|
||||
#import <AsyncDisplayKit/ASLayout.h>
|
||||
#import <AsyncDisplayKit/ASDimension.h>
|
||||
#import <AsyncDisplayKit/ASLayoutable.h>
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
3EC0CDCBA10D483D9F386E5E /* libPods.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3D24B17D1E4A4E7A9566C5E9 /* libPods.a */; };
|
||||
6C2C82AC19EE274300767484 /* Default-667h@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 6C2C82AA19EE274300767484 /* Default-667h@2x.png */; };
|
||||
6C2C82AD19EE274300767484 /* Default-736h@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 6C2C82AB19EE274300767484 /* Default-736h@3x.png */; };
|
||||
ACC945AE1BA9EFBA005E1FB8 /* ScreenNode.m in Sources */ = {isa = PBXBuildFile; fileRef = ACC945AD1BA9EFBA005E1FB8 /* ScreenNode.m */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
@@ -29,6 +30,8 @@
|
||||
3D24B17D1E4A4E7A9566C5E9 /* libPods.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libPods.a; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
6C2C82AA19EE274300767484 /* Default-667h@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-667h@2x.png"; sourceTree = SOURCE_ROOT; };
|
||||
6C2C82AB19EE274300767484 /* Default-736h@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-736h@3x.png"; sourceTree = SOURCE_ROOT; };
|
||||
ACC945AC1BA9EFB3005E1FB8 /* ScreenNode.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ScreenNode.h; sourceTree = "<group>"; };
|
||||
ACC945AD1BA9EFBA005E1FB8 /* ScreenNode.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ScreenNode.m; sourceTree = "<group>"; };
|
||||
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>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
@@ -72,6 +75,8 @@
|
||||
05E2128919D4DB510098F589 /* AppDelegate.m */,
|
||||
05E2128B19D4DB510098F589 /* ViewController.h */,
|
||||
05E2128C19D4DB510098F589 /* ViewController.m */,
|
||||
ACC945AC1BA9EFB3005E1FB8 /* ScreenNode.h */,
|
||||
ACC945AD1BA9EFBA005E1FB8 /* ScreenNode.m */,
|
||||
05E2128419D4DB510098F589 /* Supporting Files */,
|
||||
);
|
||||
path = Sample;
|
||||
@@ -214,6 +219,7 @@
|
||||
05E2128D19D4DB510098F589 /* ViewController.m in Sources */,
|
||||
05E2128A19D4DB510098F589 /* AppDelegate.m in Sources */,
|
||||
05E2128719D4DB510098F589 /* main.m in Sources */,
|
||||
ACC945AE1BA9EFBA005E1FB8 /* ScreenNode.m in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
||||
19
examples/Multiplex/Sample/ScreenNode.h
Normal file
19
examples/Multiplex/Sample/ScreenNode.h
Normal file
@@ -0,0 +1,19 @@
|
||||
//
|
||||
// ScreenNode.h
|
||||
// Sample
|
||||
//
|
||||
// Created by Huy Nguyen on 16/09/15.
|
||||
// Copyright (c) 2015 Facebook. All rights reserved.
|
||||
//
|
||||
|
||||
#import <AsyncDisplayKit/AsyncDisplayKit.h>
|
||||
|
||||
@interface ScreenNode : ASDisplayNode
|
||||
|
||||
@property (nonatomic, strong) ASMultiplexImageNode *imageNode;
|
||||
@property (nonatomic, strong) ASTextNode *textNode;
|
||||
|
||||
- (void)start;
|
||||
- (void)reload;
|
||||
|
||||
@end
|
||||
156
examples/Multiplex/Sample/ScreenNode.m
Normal file
156
examples/Multiplex/Sample/ScreenNode.m
Normal file
@@ -0,0 +1,156 @@
|
||||
//
|
||||
// ScreenNode.m
|
||||
// Sample
|
||||
//
|
||||
// Created by Huy Nguyen on 16/09/15.
|
||||
// Copyright (c) 2015 Facebook. All rights reserved.
|
||||
//
|
||||
|
||||
#import "ScreenNode.h"
|
||||
#import "AsyncDisplayKit/AsyncDisplayKit.h"
|
||||
|
||||
@interface ScreenNode() <ASMultiplexImageNodeDataSource, ASMultiplexImageNodeDelegate, ASImageDownloaderProtocol>
|
||||
@end
|
||||
|
||||
@implementation ScreenNode
|
||||
|
||||
- (instancetype)init
|
||||
{
|
||||
if (!(self = [super init])) {
|
||||
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
|
||||
_textNode = [[ASTextNode alloc] init];
|
||||
|
||||
[self addSubnode:_imageNode];
|
||||
[self addSubnode:_textNode];
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)start
|
||||
{
|
||||
[self setText:@"loading…"];
|
||||
_textNode.userInteractionEnabled = NO;
|
||||
_imageNode.imageIdentifiers = @[ @"best", @"medium", @"worst" ]; // go!
|
||||
}
|
||||
|
||||
- (void)reload {
|
||||
[self start];
|
||||
[_imageNode reloadImageIdentifierSources];
|
||||
}
|
||||
|
||||
- (void)setText:(NSString *)text
|
||||
{
|
||||
NSDictionary *attributes = @{NSFontAttributeName: [UIFont fontWithName:@"HelveticaNeue-Light" size:22.0f]};
|
||||
NSAttributedString *string = [[NSAttributedString alloc] initWithString:text
|
||||
attributes:attributes];
|
||||
_textNode.attributedString = string;
|
||||
[self setNeedsLayout];
|
||||
}
|
||||
|
||||
- (ASLayoutSpec *)layoutSpecThatFits:(ASSizeRange)constrainedSize
|
||||
{
|
||||
return
|
||||
[ASInsetLayoutSpec
|
||||
insetLayoutSpecWithInsets:UIEdgeInsetsMake(10, 10, 10, 10)
|
||||
child:
|
||||
[ASStackLayoutSpec
|
||||
stackLayoutSpecWithDirection:ASStackLayoutDirectionVertical
|
||||
spacing:10
|
||||
justifyContent:ASStackLayoutJustifyContentCenter
|
||||
alignItems:ASStackLayoutAlignItemsCenter
|
||||
children:@[[ASRatioLayoutSpec ratioLayoutSpecWithRatio:1 child:_imageNode], _textNode]]];
|
||||
}
|
||||
|
||||
#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
|
||||
{
|
||||
[self setText:[NSString stringWithFormat:@"loaded '%@'", imageIdentifier]];
|
||||
|
||||
if ([imageIdentifier isEqualToString:@"best"]) {
|
||||
[self setText:[_textNode.attributedString.string stringByAppendingString:@". tap to reload"]];
|
||||
_textNode.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
|
||||
@@ -9,8 +9,8 @@
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
#import <AsyncDisplayKit/ASViewController.h>
|
||||
|
||||
@interface ViewController : UIViewController
|
||||
@interface ViewController : ASViewController
|
||||
|
||||
@end
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user