mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-22 14:20:20 +00:00
Merge branch 'master' into update-objc
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -1,4 +1,4 @@
|
|||||||
DS_Store
|
.DS_Store
|
||||||
|
|
||||||
*.pbxuser
|
*.pbxuser
|
||||||
*.perspective
|
*.perspective
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
19
AsyncDisplayKit/ASViewController.h
Normal file
19
AsyncDisplayKit/ASViewController.h
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
//
|
||||||
|
// ASViewController.h
|
||||||
|
// AsyncDisplayKit
|
||||||
|
//
|
||||||
|
// Created by Huy Nguyen on 16/09/15.
|
||||||
|
// Copyright (c) 2015 Facebook. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import <UIKit/UIKit.h>
|
||||||
|
#import <AsyncDisplayKit/ASDisplayNode.h>
|
||||||
|
|
||||||
|
@interface ASViewController : UIViewController
|
||||||
|
|
||||||
|
@property (nonatomic, strong, readonly) ASDisplayNode *node;
|
||||||
|
|
||||||
|
//TODO Use nonnull annotation late on. Travis doesn't recognize it (yet).
|
||||||
|
- (instancetype)initWithNode:(ASDisplayNode *)node;
|
||||||
|
|
||||||
|
@end
|
||||||
48
AsyncDisplayKit/ASViewController.m
Normal file
48
AsyncDisplayKit/ASViewController.m
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
//
|
||||||
|
// 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
|
||||||
|
{
|
||||||
|
CGSize viewSize = self.view.bounds.size;
|
||||||
|
ASSizeRange constrainedSize = ASSizeRangeMake(viewSize, viewSize);
|
||||||
|
[_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>
|
||||||
@@ -49,6 +51,7 @@
|
|||||||
#import <AsyncDisplayKit/ASControlNode+Subclasses.h>
|
#import <AsyncDisplayKit/ASControlNode+Subclasses.h>
|
||||||
#import <AsyncDisplayKit/ASDisplayNode+Subclasses.h>
|
#import <AsyncDisplayKit/ASDisplayNode+Subclasses.h>
|
||||||
#import <AsyncDisplayKit/ASDisplayNodeExtraIvars.h>
|
#import <AsyncDisplayKit/ASDisplayNodeExtraIvars.h>
|
||||||
|
#import <AsyncDisplayKit/ASEqualityHelpers.h>
|
||||||
#import <AsyncDisplayKit/ASHighlightOverlayLayer.h>
|
#import <AsyncDisplayKit/ASHighlightOverlayLayer.h>
|
||||||
#import <AsyncDisplayKit/ASIndexPath.h>
|
#import <AsyncDisplayKit/ASIndexPath.h>
|
||||||
#import <AsyncDisplayKit/ASLayoutOptions.h>
|
#import <AsyncDisplayKit/ASLayoutOptions.h>
|
||||||
@@ -57,7 +60,6 @@
|
|||||||
#import <AsyncDisplayKit/ASRangeHandler.h>
|
#import <AsyncDisplayKit/ASRangeHandler.h>
|
||||||
#import <AsyncDisplayKit/ASRangeHandlerPreload.h>
|
#import <AsyncDisplayKit/ASRangeHandlerPreload.h>
|
||||||
#import <AsyncDisplayKit/ASRangeHandlerRender.h>
|
#import <AsyncDisplayKit/ASRangeHandlerRender.h>
|
||||||
//#import <AsyncDisplayKit/ASStackUnpositionedLayout.h>
|
|
||||||
#import <AsyncDisplayKit/ASTextNodeCoreTextAdditions.h>
|
#import <AsyncDisplayKit/ASTextNodeCoreTextAdditions.h>
|
||||||
#import <AsyncDisplayKit/ASTextNodeRenderer.h>
|
#import <AsyncDisplayKit/ASTextNodeRenderer.h>
|
||||||
#import <AsyncDisplayKit/ASTextNodeShadower.h>
|
#import <AsyncDisplayKit/ASTextNodeShadower.h>
|
||||||
@@ -65,5 +67,7 @@
|
|||||||
#import <AsyncDisplayKit/ASTextNodeTypes.h>
|
#import <AsyncDisplayKit/ASTextNodeTypes.h>
|
||||||
#import <AsyncDisplayKit/ASTextNodeWordKerner.h>
|
#import <AsyncDisplayKit/ASTextNodeWordKerner.h>
|
||||||
#import <AsyncDisplayKit/ASThread.h>
|
#import <AsyncDisplayKit/ASThread.h>
|
||||||
|
#import <AsyncDisplayKit/CGRect+ASConvenience.h>
|
||||||
#import <AsyncDisplayKit/NSMutableAttributedString+TextKitAdditions.h>
|
#import <AsyncDisplayKit/NSMutableAttributedString+TextKitAdditions.h>
|
||||||
|
#import <AsyncDisplayKit/UICollectionViewLayout+ASConvenience.h>
|
||||||
#import <AsyncDisplayKit/UIView+ASConvenience.h>
|
#import <AsyncDisplayKit/UIView+ASConvenience.h>
|
||||||
|
|||||||
@@ -64,7 +64,7 @@
|
|||||||
*
|
*
|
||||||
* @param layoutOptions The layoutOptions to copy from
|
* @param layoutOptions The layoutOptions to copy from
|
||||||
*/
|
*/
|
||||||
- (void)copyIntoOptions:(ASLayoutOptions *)layoutOptions;
|
- (void)copyFromOptions:(ASLayoutOptions *)layoutOptions;
|
||||||
|
|
||||||
#pragma mark - ASStackLayoutable
|
#pragma mark - ASStackLayoutable
|
||||||
|
|
||||||
|
|||||||
@@ -86,11 +86,11 @@ static Class gDefaultLayoutOptionsClass = nil;
|
|||||||
- (id)copyWithZone:(NSZone *)zone
|
- (id)copyWithZone:(NSZone *)zone
|
||||||
{
|
{
|
||||||
ASLayoutOptions *copy = [[[self class] alloc] init];
|
ASLayoutOptions *copy = [[[self class] alloc] init];
|
||||||
[copy copyIntoOptions:self];
|
[copy copyFromOptions:self];
|
||||||
return copy;
|
return copy;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)copyIntoOptions:(ASLayoutOptions *)layoutOptions
|
- (void)copyFromOptions:(ASLayoutOptions *)layoutOptions
|
||||||
{
|
{
|
||||||
ASDN::MutexLocker l(_propertyLock);
|
ASDN::MutexLocker l(_propertyLock);
|
||||||
self.flexBasis = layoutOptions.flexBasis;
|
self.flexBasis = layoutOptions.flexBasis;
|
||||||
|
|||||||
@@ -82,7 +82,7 @@ static NSString * const kDefaultChildrenKey = @"kDefaultChildrenKey";
|
|||||||
|
|
||||||
id<ASLayoutable> finalLayoutable = [child finalLayoutable];
|
id<ASLayoutable> finalLayoutable = [child finalLayoutable];
|
||||||
if (finalLayoutable != child) {
|
if (finalLayoutable != child) {
|
||||||
[finalLayoutable.layoutOptions copyIntoOptions:child.layoutOptions];
|
[finalLayoutable.layoutOptions copyFromOptions:child.layoutOptions];
|
||||||
return finalLayoutable;
|
return finalLayoutable;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
19
AsyncDisplayKit/module.modulemap
Normal file
19
AsyncDisplayKit/module.modulemap
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
framework module AsyncDisplayKit {
|
||||||
|
umbrella header "AsyncDisplayKit.h"
|
||||||
|
|
||||||
|
export *
|
||||||
|
module * {
|
||||||
|
export *
|
||||||
|
}
|
||||||
|
|
||||||
|
explicit module ASControlNode_Subclasses {
|
||||||
|
header "ASControlNode+Subclasses.h"
|
||||||
|
export *
|
||||||
|
}
|
||||||
|
|
||||||
|
explicit module ASDisplayNode_Subclasses {
|
||||||
|
header "ASDisplayNode+Subclasses.h"
|
||||||
|
export *
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -6,8 +6,8 @@
|
|||||||
* of patent rights can be found in the PATENTS file in the same directory.
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#import <AsyncDisplayKit/ASBasicImageDownloaderInternal.h>
|
|
||||||
#import <AsyncDisplayKit/ASBasicImageDownloader.h>
|
#import <AsyncDisplayKit/ASBasicImageDownloader.h>
|
||||||
|
#import "ASBasicImageDownloaderInternal.h"
|
||||||
|
|
||||||
#import <OCMock/OCMock.h>
|
#import <OCMock/OCMock.h>
|
||||||
|
|
||||||
|
|||||||
@@ -7,8 +7,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#import "ASSnapshotTestCase.h"
|
#import "ASSnapshotTestCase.h"
|
||||||
|
#import "ASDisplayNodeInternal.h"
|
||||||
#import <AsyncDisplayKit/ASDisplayNodeInternal.h>
|
|
||||||
|
|
||||||
@implementation ASSnapshotTestCase
|
@implementation ASSnapshotTestCase
|
||||||
|
|
||||||
|
|||||||
@@ -379,7 +379,7 @@
|
|||||||
}];
|
}];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)testRelayoutRowsAfterEditingModeIsChangedAndTheyBecomeVisible
|
- (void)DISABLED_testRelayoutRowsAfterEditingModeIsChangedAndTheyBecomeVisible
|
||||||
{
|
{
|
||||||
CGSize tableViewSize = CGSizeMake(100, 500);
|
CGSize tableViewSize = CGSizeMake(100, 500);
|
||||||
ASTestTableView *tableView = [[ASTestTableView alloc] initWithFrame:CGRectMake(0, 0, tableViewSize.width, tableViewSize.height)
|
ASTestTableView *tableView = [[ASTestTableView alloc] initWithFrame:CGRectMake(0, 0, tableViewSize.width, tableViewSize.height)
|
||||||
|
|||||||
@@ -77,8 +77,11 @@
|
|||||||
AC3C4A8D1A11F80C00143C57 /* Images.xcassets */,
|
AC3C4A8D1A11F80C00143C57 /* Images.xcassets */,
|
||||||
AC3C4A611A11F47200143C57 /* Supporting Files */,
|
AC3C4A611A11F47200143C57 /* Supporting Files */,
|
||||||
);
|
);
|
||||||
|
indentWidth = 2;
|
||||||
path = Sample;
|
path = Sample;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
|
tabWidth = 2;
|
||||||
|
usesTabs = 0;
|
||||||
};
|
};
|
||||||
AC3C4A611A11F47200143C57 /* Supporting Files */ = {
|
AC3C4A611A11F47200143C57 /* Supporting Files */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
|
|||||||
@@ -52,7 +52,10 @@
|
|||||||
1A943BF0259746F18D6E423F /* Frameworks */,
|
1A943BF0259746F18D6E423F /* Frameworks */,
|
||||||
1AE410B73DA5C3BD087ACDD7 /* Pods */,
|
1AE410B73DA5C3BD087ACDD7 /* Pods */,
|
||||||
);
|
);
|
||||||
|
indentWidth = 2;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
|
tabWidth = 2;
|
||||||
|
usesTabs = 0;
|
||||||
};
|
};
|
||||||
05E2128219D4DB510098F589 /* Products */ = {
|
05E2128219D4DB510098F589 /* Products */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
|
|||||||
@@ -52,7 +52,10 @@
|
|||||||
1A943BF0259746F18D6E423F /* Frameworks */,
|
1A943BF0259746F18D6E423F /* Frameworks */,
|
||||||
1AE410B73DA5C3BD087ACDD7 /* Pods */,
|
1AE410B73DA5C3BD087ACDD7 /* Pods */,
|
||||||
);
|
);
|
||||||
|
indentWidth = 2;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
|
tabWidth = 2;
|
||||||
|
usesTabs = 0;
|
||||||
};
|
};
|
||||||
05E2128219D4DB510098F589 /* Products */ = {
|
05E2128219D4DB510098F589 /* Products */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
|
|||||||
@@ -58,7 +58,10 @@
|
|||||||
1A943BF0259746F18D6E423F /* Frameworks */,
|
1A943BF0259746F18D6E423F /* Frameworks */,
|
||||||
1AE410B73DA5C3BD087ACDD7 /* Pods */,
|
1AE410B73DA5C3BD087ACDD7 /* Pods */,
|
||||||
);
|
);
|
||||||
|
indentWidth = 2;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
|
tabWidth = 2;
|
||||||
|
usesTabs = 0;
|
||||||
};
|
};
|
||||||
05E2128219D4DB510098F589 /* Products */ = {
|
05E2128219D4DB510098F589 /* Products */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
|
|||||||
@@ -61,6 +61,7 @@
|
|||||||
indentWidth = 2;
|
indentWidth = 2;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
tabWidth = 2;
|
tabWidth = 2;
|
||||||
|
usesTabs = 0;
|
||||||
};
|
};
|
||||||
05E2128219D4DB510098F589 /* Products */ = {
|
05E2128219D4DB510098F589 /* Products */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
|
|||||||
@@ -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 */
|
||||||
|
|
||||||
@@ -52,7 +55,10 @@
|
|||||||
1A943BF0259746F18D6E423F /* Frameworks */,
|
1A943BF0259746F18D6E423F /* Frameworks */,
|
||||||
1AE410B73DA5C3BD087ACDD7 /* Pods */,
|
1AE410B73DA5C3BD087ACDD7 /* Pods */,
|
||||||
);
|
);
|
||||||
|
indentWidth = 2;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
|
tabWidth = 2;
|
||||||
|
usesTabs = 0;
|
||||||
};
|
};
|
||||||
05E2128219D4DB510098F589 /* Products */ = {
|
05E2128219D4DB510098F589 /* Products */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
@@ -69,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;
|
||||||
@@ -211,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
|
||||||
152
examples/Multiplex/Sample/ScreenNode.m
Normal file
152
examples/Multiplex/Sample/ScreenNode.m
Normal file
@@ -0,0 +1,152 @@
|
|||||||
|
//
|
||||||
|
// ScreenNode.m
|
||||||
|
// Sample
|
||||||
|
//
|
||||||
|
// Created by Huy Nguyen on 16/09/15.
|
||||||
|
// Copyright (c) 2015 Facebook. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import "ScreenNode.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
|
||||||
|
{
|
||||||
|
ASRatioLayoutSpec *imagePlaceholder = [ASRatioLayoutSpec ratioLayoutSpecWithRatio:1 child:_imageNode];
|
||||||
|
ASStackLayoutSpec *verticalStack = [ASStackLayoutSpec stackLayoutSpecWithDirection:ASStackLayoutDirectionVertical
|
||||||
|
spacing:10
|
||||||
|
justifyContent:ASStackLayoutJustifyContentCenter
|
||||||
|
alignItems:ASStackLayoutAlignItemsCenter
|
||||||
|
children:@[imagePlaceholder, _textNode]];
|
||||||
|
return [ASInsetLayoutSpec insetLayoutSpecWithInsets:UIEdgeInsetsMake(10, 10, 10, 10) child:verticalStack];
|
||||||
|
}
|
||||||
|
|
||||||
|
#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,40 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#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];
|
// This should be done before calling super's viewWillAppear which triggers data fetching on the node.
|
||||||
|
[_screenNode start];
|
||||||
[self.view addSubnode:_imageNode];
|
[super viewWillAppear:animated];
|
||||||
[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 +51,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
|
||||||
|
|||||||
@@ -66,7 +66,10 @@
|
|||||||
1A943BF0259746F18D6E423F /* Frameworks */,
|
1A943BF0259746F18D6E423F /* Frameworks */,
|
||||||
1AE410B73DA5C3BD087ACDD7 /* Pods */,
|
1AE410B73DA5C3BD087ACDD7 /* Pods */,
|
||||||
);
|
);
|
||||||
|
indentWidth = 2;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
|
tabWidth = 2;
|
||||||
|
usesTabs = 0;
|
||||||
};
|
};
|
||||||
05E2128219D4DB510098F589 /* Products */ = {
|
05E2128219D4DB510098F589 /* Products */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
|
|||||||
@@ -52,6 +52,7 @@
|
|||||||
indentWidth = 2;
|
indentWidth = 2;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
tabWidth = 2;
|
tabWidth = 2;
|
||||||
|
usesTabs = 0;
|
||||||
};
|
};
|
||||||
050E7C6F19D22E19004363C2 /* Products */ = {
|
050E7C6F19D22E19004363C2 /* Products */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
|
|||||||
@@ -57,7 +57,10 @@
|
|||||||
058968F11ABCE06E0059CE2A /* Life Without CocoaPods */,
|
058968F11ABCE06E0059CE2A /* Life Without CocoaPods */,
|
||||||
058968F01ABCE06E0059CE2A /* Products */,
|
058968F01ABCE06E0059CE2A /* Products */,
|
||||||
);
|
);
|
||||||
|
indentWidth = 2;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
|
tabWidth = 2;
|
||||||
|
usesTabs = 0;
|
||||||
};
|
};
|
||||||
058968F01ABCE06E0059CE2A /* Products */ = {
|
058968F01ABCE06E0059CE2A /* Products */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
|
|||||||
Reference in New Issue
Block a user