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, ); }; };
|
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 */; };
|
AC47D9461B3BB41900AAEE9D /* ASRelativeSize.mm in Sources */ = {isa = PBXBuildFile; fileRef = AC47D9441B3BB41900AAEE9D /* ASRelativeSize.mm */; };
|
||||||
AC6456091B0A335000CF11B8 /* ASCellNode.m in Sources */ = {isa = PBXBuildFile; fileRef = AC6456071B0A335000CF11B8 /* ASCellNode.m */; };
|
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, ); }; };
|
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 */; };
|
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, ); }; };
|
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>"; };
|
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>"; };
|
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>"; };
|
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>"; };
|
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>"; };
|
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>"; };
|
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 */,
|
0574D5E119C110610097DC25 /* ASTableViewProtocols.h */,
|
||||||
058D09DF195D050800B7D73C /* ASTextNode.h */,
|
058D09DF195D050800B7D73C /* ASTextNode.h */,
|
||||||
058D09E0195D050800B7D73C /* ASTextNode.mm */,
|
058D09E0195D050800B7D73C /* ASTextNode.mm */,
|
||||||
|
ACC945A81BA9E7A0005E1FB8 /* ASViewController.h */,
|
||||||
|
ACC945AA1BA9E7C1005E1FB8 /* ASViewController.m */,
|
||||||
6BDC61F51978FEA400E50D21 /* AsyncDisplayKit.h */,
|
6BDC61F51978FEA400E50D21 /* AsyncDisplayKit.h */,
|
||||||
058D09E1195D050800B7D73C /* Details */,
|
058D09E1195D050800B7D73C /* Details */,
|
||||||
058D0A01195D050800B7D73C /* Private */,
|
058D0A01195D050800B7D73C /* Private */,
|
||||||
@@ -1114,6 +1120,7 @@
|
|||||||
058D0A63195D05DC00B7D73C /* ASTextNodeTypes.h in Headers */,
|
058D0A63195D05DC00B7D73C /* ASTextNodeTypes.h in Headers */,
|
||||||
058D0A64195D05DC00B7D73C /* ASTextNodeWordKerner.h in Headers */,
|
058D0A64195D05DC00B7D73C /* ASTextNodeWordKerner.h in Headers */,
|
||||||
058D0A81195D05F900B7D73C /* ASThread.h in Headers */,
|
058D0A81195D05F900B7D73C /* ASThread.h in Headers */,
|
||||||
|
ACC945A91BA9E7A0005E1FB8 /* ASViewController.h in Headers */,
|
||||||
6BDC61F61979037800E50D21 /* AsyncDisplayKit.h in Headers */,
|
6BDC61F61979037800E50D21 /* AsyncDisplayKit.h in Headers */,
|
||||||
205F0E211B376416007741D0 /* CGRect+ASConvenience.h in Headers */,
|
205F0E211B376416007741D0 /* CGRect+ASConvenience.h in Headers */,
|
||||||
058D0A66195D05DC00B7D73C /* NSMutableAttributedString+TextKitAdditions.h in Headers */,
|
058D0A66195D05DC00B7D73C /* NSMutableAttributedString+TextKitAdditions.h in Headers */,
|
||||||
@@ -1478,6 +1485,7 @@
|
|||||||
058D0A1E195D050800B7D73C /* ASTextNodeShadower.m in Sources */,
|
058D0A1E195D050800B7D73C /* ASTextNodeShadower.m in Sources */,
|
||||||
058D0A1F195D050800B7D73C /* ASTextNodeTextKitHelpers.mm in Sources */,
|
058D0A1F195D050800B7D73C /* ASTextNodeTextKitHelpers.mm in Sources */,
|
||||||
058D0A20195D050800B7D73C /* ASTextNodeWordKerner.m in Sources */,
|
058D0A20195D050800B7D73C /* ASTextNodeWordKerner.m in Sources */,
|
||||||
|
ACC945AB1BA9E7C1005E1FB8 /* ASViewController.m in Sources */,
|
||||||
205F0E221B376416007741D0 /* CGRect+ASConvenience.m in Sources */,
|
205F0E221B376416007741D0 /* CGRect+ASConvenience.m in Sources */,
|
||||||
058D0A21195D050800B7D73C /* NSMutableAttributedString+TextKitAdditions.m in Sources */,
|
058D0A21195D050800B7D73C /* NSMutableAttributedString+TextKitAdditions.m in Sources */,
|
||||||
205F0E101B371875007741D0 /* UICollectionViewLayout+ASConvenience.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/ASScrollNode.h>
|
||||||
|
|
||||||
|
#import <AsyncDisplayKit/ASViewController.h>
|
||||||
|
|
||||||
#import <AsyncDisplayKit/ASLayout.h>
|
#import <AsyncDisplayKit/ASLayout.h>
|
||||||
#import <AsyncDisplayKit/ASDimension.h>
|
#import <AsyncDisplayKit/ASDimension.h>
|
||||||
#import <AsyncDisplayKit/ASLayoutable.h>
|
#import <AsyncDisplayKit/ASLayoutable.h>
|
||||||
|
|||||||
@@ -14,6 +14,7 @@
|
|||||||
3EC0CDCBA10D483D9F386E5E /* libPods.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3D24B17D1E4A4E7A9566C5E9 /* libPods.a */; };
|
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 */; };
|
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 */; };
|
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 */
|
/* End PBXBuildFile section */
|
||||||
|
|
||||||
/* Begin PBXFileReference 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; };
|
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; };
|
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; };
|
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>"; };
|
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 */
|
/* End PBXFileReference section */
|
||||||
|
|
||||||
@@ -72,6 +75,8 @@
|
|||||||
05E2128919D4DB510098F589 /* AppDelegate.m */,
|
05E2128919D4DB510098F589 /* AppDelegate.m */,
|
||||||
05E2128B19D4DB510098F589 /* ViewController.h */,
|
05E2128B19D4DB510098F589 /* ViewController.h */,
|
||||||
05E2128C19D4DB510098F589 /* ViewController.m */,
|
05E2128C19D4DB510098F589 /* ViewController.m */,
|
||||||
|
ACC945AC1BA9EFB3005E1FB8 /* ScreenNode.h */,
|
||||||
|
ACC945AD1BA9EFBA005E1FB8 /* ScreenNode.m */,
|
||||||
05E2128419D4DB510098F589 /* Supporting Files */,
|
05E2128419D4DB510098F589 /* Supporting Files */,
|
||||||
);
|
);
|
||||||
path = Sample;
|
path = Sample;
|
||||||
@@ -214,6 +219,7 @@
|
|||||||
05E2128D19D4DB510098F589 /* ViewController.m in Sources */,
|
05E2128D19D4DB510098F589 /* ViewController.m in Sources */,
|
||||||
05E2128A19D4DB510098F589 /* AppDelegate.m in Sources */,
|
05E2128A19D4DB510098F589 /* AppDelegate.m in Sources */,
|
||||||
05E2128719D4DB510098F589 /* main.m in Sources */,
|
05E2128719D4DB510098F589 /* main.m in Sources */,
|
||||||
|
ACC945AE1BA9EFBA005E1FB8 /* ScreenNode.m in Sources */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
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.
|
* 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
|
@end
|
||||||
|
|||||||
@@ -10,77 +10,39 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#import "ViewController.h"
|
#import "ViewController.h"
|
||||||
|
#import "ScreenNode.h"
|
||||||
|
|
||||||
#import <AsyncDisplayKit/AsyncDisplayKit.h>
|
@interface ViewController() {
|
||||||
|
ScreenNode *_screenNode;
|
||||||
|
|
||||||
@interface ViewController () <ASMultiplexImageNodeDataSource, ASMultiplexImageNodeDelegate, ASImageDownloaderProtocol>
|
|
||||||
{
|
|
||||||
ASMultiplexImageNode *_imageNode;
|
|
||||||
|
|
||||||
UILabel *_textLabel;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
|
||||||
@implementation ViewController
|
@implementation ViewController
|
||||||
|
|
||||||
- (instancetype)init
|
- (instancetype)init
|
||||||
{
|
{
|
||||||
if (!(self = [super init]))
|
ScreenNode *node = [[ScreenNode alloc] init];
|
||||||
|
if (!(self = [super initWithNode:node]))
|
||||||
return nil;
|
return nil;
|
||||||
|
|
||||||
|
_screenNode = node;
|
||||||
// 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];
|
|
||||||
|
|
||||||
// tap to reload
|
// tap to reload
|
||||||
UITapGestureRecognizer *gr = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(reload:)];
|
UITapGestureRecognizer *gr = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(reload:)];
|
||||||
[_textLabel addGestureRecognizer:gr];
|
[_screenNode.textNode.view addGestureRecognizer:gr];
|
||||||
|
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)viewDidLoad
|
- (void)viewWillAppear:(BOOL)animated
|
||||||
{
|
{
|
||||||
[super viewDidLoad];
|
[super viewWillAppear:animated];
|
||||||
|
[_screenNode start];
|
||||||
[self.view addSubnode:_imageNode];
|
|
||||||
[self.view addSubview:_textLabel];
|
|
||||||
|
|
||||||
[self start];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)viewWillLayoutSubviews
|
- (void)reload:(id)sender {
|
||||||
{
|
[_screenNode reload];
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (BOOL)prefersStatusBarHidden
|
- (BOOL)prefersStatusBarHidden
|
||||||
@@ -88,95 +50,4 @@
|
|||||||
return YES;
|
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
|
@end
|
||||||
|
|||||||
Reference in New Issue
Block a user