mirror of
https://github.com/HackPlan/AsyncDisplayKit.git
synced 2026-03-29 22:36:09 +08:00
Merge branch 'master' into ASVideoNode
This commit is contained in:
@@ -360,6 +360,10 @@
|
||||
AEEC47E41C21D3D200EC1693 /* ASVideoNodeTests.m in Sources */ = {isa = PBXBuildFile; fileRef = AEEC47E31C21D3D200EC1693 /* ASVideoNodeTests.m */; };
|
||||
B0F8805A1BEAEC7500D17647 /* ASTableNode.h in Headers */ = {isa = PBXBuildFile; fileRef = B0F880581BEAEC7500D17647 /* ASTableNode.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
B0F8805B1BEAEC7500D17647 /* ASTableNode.m in Sources */ = {isa = PBXBuildFile; fileRef = B0F880591BEAEC7500D17647 /* ASTableNode.m */; };
|
||||
B13CA0F71C519E9400E031AB /* ASCollectionViewLayoutFacilitatorProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = B13CA0F61C519E9400E031AB /* ASCollectionViewLayoutFacilitatorProtocol.h */; };
|
||||
B13CA0F81C519EBA00E031AB /* ASCollectionViewLayoutFacilitatorProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = B13CA0F61C519E9400E031AB /* ASCollectionViewLayoutFacilitatorProtocol.h */; };
|
||||
B13CA1001C52004900E031AB /* ASCollectionNode+Beta.h in Headers */ = {isa = PBXBuildFile; fileRef = B13CA0FF1C52004900E031AB /* ASCollectionNode+Beta.h */; };
|
||||
B13CA1011C52004900E031AB /* ASCollectionNode+Beta.h in Headers */ = {isa = PBXBuildFile; fileRef = B13CA0FF1C52004900E031AB /* ASCollectionNode+Beta.h */; };
|
||||
B35061F31B010EFD0018CF92 /* ASCellNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 055F1A3A19ABD43F004DAFF1 /* ASCellNode.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
B35061F51B010EFD0018CF92 /* ASCollectionView.h in Headers */ = {isa = PBXBuildFile; fileRef = AC3C4A4F1A1139C100143C57 /* ASCollectionView.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
B35061F61B010EFD0018CF92 /* ASCollectionView.mm in Sources */ = {isa = PBXBuildFile; fileRef = AC3C4A501A1139C100143C57 /* ASCollectionView.mm */; };
|
||||
@@ -771,6 +775,8 @@
|
||||
AEEC47E31C21D3D200EC1693 /* ASVideoNodeTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASVideoNodeTests.m; sourceTree = "<group>"; };
|
||||
B0F880581BEAEC7500D17647 /* ASTableNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASTableNode.h; sourceTree = "<group>"; };
|
||||
B0F880591BEAEC7500D17647 /* ASTableNode.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASTableNode.m; sourceTree = "<group>"; };
|
||||
B13CA0F61C519E9400E031AB /* ASCollectionViewLayoutFacilitatorProtocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASCollectionViewLayoutFacilitatorProtocol.h; sourceTree = "<group>"; };
|
||||
B13CA0FF1C52004900E031AB /* ASCollectionNode+Beta.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "ASCollectionNode+Beta.h"; sourceTree = "<group>"; };
|
||||
B35061DA1B010EDF0018CF92 /* AsyncDisplayKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = AsyncDisplayKit.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
B35061DD1B010EDF0018CF92 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = Info.plist; path = "../AsyncDisplayKit-iOS/Info.plist"; sourceTree = "<group>"; };
|
||||
CC7FD9DC1BB5E962005CCB2B /* ASPhotosFrameworkImageRequest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASPhotosFrameworkImageRequest.h; sourceTree = "<group>"; };
|
||||
@@ -913,9 +919,11 @@
|
||||
AC6456071B0A335000CF11B8 /* ASCellNode.m */,
|
||||
18C2ED7C1B9B7DE800F627B3 /* ASCollectionNode.h */,
|
||||
18C2ED7D1B9B7DE800F627B3 /* ASCollectionNode.mm */,
|
||||
B13CA0FF1C52004900E031AB /* ASCollectionNode+Beta.h */,
|
||||
AC3C4A4F1A1139C100143C57 /* ASCollectionView.h */,
|
||||
AC3C4A501A1139C100143C57 /* ASCollectionView.mm */,
|
||||
AC3C4A531A113EEC00143C57 /* ASCollectionViewProtocols.h */,
|
||||
B13CA0F61C519E9400E031AB /* ASCollectionViewLayoutFacilitatorProtocol.h */,
|
||||
DEC146B41C37A16A004A0EE7 /* ASCollectionInternal.h */,
|
||||
DEC146B51C37A16A004A0EE7 /* ASCollectionInternal.m */,
|
||||
058D09D5195D050800B7D73C /* ASControlNode.h */,
|
||||
@@ -1285,6 +1293,7 @@
|
||||
058D0A72195D05F800B7D73C /* _ASCoreAnimationExtras.h in Headers */,
|
||||
058D0A53195D05DC00B7D73C /* _ASDisplayLayer.h in Headers */,
|
||||
058D0A55195D05DC00B7D73C /* _ASDisplayView.h in Headers */,
|
||||
B13CA0F71C519E9400E031AB /* ASCollectionViewLayoutFacilitatorProtocol.h in Headers */,
|
||||
058D0A74195D05F800B7D73C /* _ASPendingState.h in Headers */,
|
||||
9C5586691BD549CB00B50E3A /* ASAsciiArtBoxCreator.h in Headers */,
|
||||
058D0A76195D05F900B7D73C /* _ASScopeTimer.h in Headers */,
|
||||
@@ -1356,6 +1365,7 @@
|
||||
AC026B6F1BD57DBF00BBC17E /* _ASHierarchyChangeSet.h in Headers */,
|
||||
0516FA3D1A15563400B4EBED /* ASLog.h in Headers */,
|
||||
257754AA1BEE44CD00737CA5 /* ASTextKitEntityAttribute.h in Headers */,
|
||||
B13CA1001C52004900E031AB /* ASCollectionNode+Beta.h in Headers */,
|
||||
0442850D1BAA64EC00D16268 /* ASMultidimensionalArrayUtils.h in Headers */,
|
||||
0516FA401A1563D200B4EBED /* ASMultiplexImageNode.h in Headers */,
|
||||
058D0A59195D05DC00B7D73C /* ASMutableAttributedStringBuilder.h in Headers */,
|
||||
@@ -1410,6 +1420,7 @@
|
||||
B350623C1B010EFD0018CF92 /* _ASAsyncTransaction.h in Headers */,
|
||||
B350623E1B010EFD0018CF92 /* _ASAsyncTransactionContainer+Private.h in Headers */,
|
||||
B350623F1B010EFD0018CF92 /* _ASAsyncTransactionContainer.h in Headers */,
|
||||
B13CA1011C52004900E031AB /* ASCollectionNode+Beta.h in Headers */,
|
||||
DECC2ECE1C35C1C600388446 /* ASRangeControllerBeta.h in Headers */,
|
||||
254C6B7E1BF94DF4003EC431 /* ASTextKitTailTruncater.h in Headers */,
|
||||
B35062411B010EFD0018CF92 /* _ASAsyncTransactionGroup.h in Headers */,
|
||||
@@ -1484,6 +1495,7 @@
|
||||
B35062041B010EFD0018CF92 /* ASMultiplexImageNode.h in Headers */,
|
||||
DECBD6E81BE56E1900CF4905 /* ASButtonNode.h in Headers */,
|
||||
B35062241B010EFD0018CF92 /* ASMutableAttributedStringBuilder.h in Headers */,
|
||||
B13CA0F81C519EBA00E031AB /* ASCollectionViewLayoutFacilitatorProtocol.h in Headers */,
|
||||
B35062061B010EFD0018CF92 /* ASNetworkImageNode.h in Headers */,
|
||||
34EFC76C1B701CED00AD841F /* ASOverlayLayoutSpec.h in Headers */,
|
||||
B35062261B010EFD0018CF92 /* ASRangeController.h in Headers */,
|
||||
@@ -2038,6 +2050,7 @@
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_ENABLE_CODE_COVERAGE = NO;
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
@@ -2078,6 +2091,7 @@
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_ENABLE_CODE_COVERAGE = NO;
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
@@ -2152,6 +2166,7 @@
|
||||
baseConfigurationReference = FB07EABBCF28656C6297BC2D /* Pods-AsyncDisplayKitTests.debug.xcconfig */;
|
||||
buildSettings = {
|
||||
BUNDLE_LOADER = "$(TEST_HOST)";
|
||||
CLANG_ENABLE_CODE_COVERAGE = YES;
|
||||
FRAMEWORK_SEARCH_PATHS = (
|
||||
"$(SDKROOT)/Developer/Library/Frameworks",
|
||||
"$(inherited)",
|
||||
@@ -2181,6 +2196,7 @@
|
||||
baseConfigurationReference = D3779BCFF841AD3EB56537ED /* Pods-AsyncDisplayKitTests.release.xcconfig */;
|
||||
buildSettings = {
|
||||
BUNDLE_LOADER = "$(TEST_HOST)";
|
||||
CLANG_ENABLE_CODE_COVERAGE = YES;
|
||||
FRAMEWORK_SEARCH_PATHS = (
|
||||
"$(SDKROOT)/Developer/Library/Frameworks",
|
||||
"$(inherited)",
|
||||
@@ -2207,6 +2223,7 @@
|
||||
B35061EE1B010EDF0018CF92 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
CLANG_ENABLE_CODE_COVERAGE = YES;
|
||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
@@ -2239,6 +2256,7 @@
|
||||
B35061EF1B010EDF0018CF92 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
CLANG_ENABLE_CODE_COVERAGE = YES;
|
||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
||||
COPY_PHASE_STRIP = NO;
|
||||
|
||||
@@ -26,7 +26,8 @@
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES">
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
codeCoverageEnabled = "YES">
|
||||
<Testables>
|
||||
</Testables>
|
||||
<AdditionalOptions>
|
||||
|
||||
@@ -72,6 +72,13 @@
|
||||
[self updateTitle];
|
||||
}
|
||||
|
||||
- (void)setDisplaysAsynchronously:(BOOL)displaysAsynchronously
|
||||
{
|
||||
[super setDisplaysAsynchronously:displaysAsynchronously];
|
||||
[self.imageNode setDisplaysAsynchronously:displaysAsynchronously];
|
||||
[self.titleNode setDisplaysAsynchronously:displaysAsynchronously];
|
||||
}
|
||||
|
||||
- (void)updateImage
|
||||
{
|
||||
ASDN::MutexLocker l(_propertyLock);
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
|
||||
@interface ASCellNode ()
|
||||
{
|
||||
ASDisplayNodeDidLoadBlock _nodeLoadedBlock;
|
||||
UIViewController *_viewController;
|
||||
ASDisplayNode *_viewControllerNode;
|
||||
}
|
||||
@@ -49,15 +48,13 @@
|
||||
ASDisplayNodeAssertNotNil(viewControllerBlock, @"should initialize with a valid block that returns a UIViewController");
|
||||
|
||||
if (viewControllerBlock) {
|
||||
_viewController = viewControllerBlock();
|
||||
|
||||
__weak UIViewController *weakViewController = _viewController;
|
||||
_viewControllerNode = [[ASDisplayNode alloc] initWithViewBlock:^UIView *{
|
||||
return weakViewController.view;
|
||||
_viewController = viewControllerBlock();
|
||||
return _viewController.view;
|
||||
} didLoadBlock:didLoadBlock];
|
||||
|
||||
[self addSubnode:_viewControllerNode];
|
||||
_nodeLoadedBlock = didLoadBlock;
|
||||
}
|
||||
|
||||
return self;
|
||||
|
||||
19
AsyncDisplayKit/ASCollectionNode+Beta.h
Normal file
19
AsyncDisplayKit/ASCollectionNode+Beta.h
Normal file
@@ -0,0 +1,19 @@
|
||||
/* Copyright (c) 2014-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*/
|
||||
|
||||
@protocol ASCollectionViewLayoutFacilitatorProtocol;
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface ASCollectionNode (Beta)
|
||||
|
||||
- (instancetype)initWithFrame:(CGRect)frame collectionViewLayout:(UICollectionViewLayout *)layout layoutFacilitator:(nullable id<ASCollectionViewLayoutFacilitatorProtocol>)layoutFacilitator;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
@@ -8,6 +8,8 @@
|
||||
|
||||
#import <AsyncDisplayKit/ASCollectionView.h>
|
||||
|
||||
@protocol ASCollectionViewLayoutFacilitatorProtocol;
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
/**
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
|
||||
#import "ASCollectionNode.h"
|
||||
#import "ASCollectionInternal.h"
|
||||
#import "ASCollectionViewLayoutFacilitatorProtocol.h"
|
||||
#import "ASDisplayNode+Subclasses.h"
|
||||
#import "ASRangeController.h"
|
||||
#include <vector>
|
||||
@@ -83,9 +84,14 @@
|
||||
}
|
||||
|
||||
- (instancetype)initWithFrame:(CGRect)frame collectionViewLayout:(UICollectionViewLayout *)layout
|
||||
{
|
||||
return [self initWithFrame:frame collectionViewLayout:layout layoutFacilitator:nil];
|
||||
}
|
||||
|
||||
- (instancetype)initWithFrame:(CGRect)frame collectionViewLayout:(UICollectionViewLayout *)layout layoutFacilitator:(id<ASCollectionViewLayoutFacilitatorProtocol>)layoutFacilitator
|
||||
{
|
||||
ASDisplayNodeViewBlock collectionViewBlock = ^UIView *{
|
||||
return [[ASCollectionView alloc] _initWithFrame:frame collectionViewLayout:layout ownedByNode:YES];
|
||||
return [[ASCollectionView alloc] _initWithFrame:CGRectZero collectionViewLayout:layout layoutFacilitator:layoutFacilitator ownedByNode:YES];
|
||||
};
|
||||
|
||||
if (self = [super initWithViewBlock:collectionViewBlock]) {
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
@protocol ASCollectionDataSource;
|
||||
@protocol ASCollectionDelegate;
|
||||
@protocol ASCollectionViewLayoutInspecting;
|
||||
@protocol ASCollectionViewLayoutFacilitatorProtocol;
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#import "ASCollectionDataController.h"
|
||||
#import "ASCollectionViewLayoutController.h"
|
||||
#import "ASCollectionViewFlowLayoutInspector.h"
|
||||
#import "ASCollectionViewLayoutFacilitatorProtocol.h"
|
||||
#import "ASDisplayNode+FrameworkPrivate.h"
|
||||
#import "ASDisplayNode+Beta.h"
|
||||
#import "ASInternalHelpers.h"
|
||||
@@ -67,6 +68,8 @@ static NSString * const kCellReuseIdentifier = @"_ASCollectionViewCell";
|
||||
ASRangeController *_rangeController;
|
||||
ASCollectionViewLayoutController *_layoutController;
|
||||
ASCollectionViewFlowLayoutInspector *_flowLayoutInspector;
|
||||
|
||||
id<ASCollectionViewLayoutFacilitatorProtocol> _layoutFacilitator;
|
||||
|
||||
BOOL _performingBatchUpdates;
|
||||
NSMutableArray *_batchUpdateBlocks;
|
||||
@@ -144,6 +147,11 @@ static NSString * const kCellReuseIdentifier = @"_ASCollectionViewCell";
|
||||
}
|
||||
|
||||
- (instancetype)_initWithFrame:(CGRect)frame collectionViewLayout:(UICollectionViewLayout *)layout ownedByNode:(BOOL)ownedByNode
|
||||
{
|
||||
return [self _initWithFrame:frame collectionViewLayout:layout layoutFacilitator:nil ownedByNode:ownedByNode];
|
||||
}
|
||||
|
||||
- (instancetype)_initWithFrame:(CGRect)frame collectionViewLayout:(UICollectionViewLayout *)layout layoutFacilitator:(id<ASCollectionViewLayoutFacilitatorProtocol>)layoutFacilitator ownedByNode:(BOOL)ownedByNode
|
||||
{
|
||||
if (!(self = [super initWithFrame:frame collectionViewLayout:layout]))
|
||||
return nil;
|
||||
@@ -195,6 +203,7 @@ static NSString * const kCellReuseIdentifier = @"_ASCollectionViewCell";
|
||||
if ([layout asdk_isFlowLayout]) {
|
||||
_layoutInspector = [self flowLayoutInspector];
|
||||
}
|
||||
_layoutFacilitator = layoutFacilitator;
|
||||
|
||||
_proxyDelegate = [[ASCollectionViewProxy alloc] initWithTarget:nil interceptor:self];
|
||||
super.delegate = (id<UICollectionViewDelegate>)_proxyDelegate;
|
||||
@@ -252,6 +261,7 @@ static NSString * const kCellReuseIdentifier = @"_ASCollectionViewCell";
|
||||
- (void)reloadDataImmediately
|
||||
{
|
||||
ASDisplayNodeAssertMainThread();
|
||||
_superIsPendingDataLoad = YES;
|
||||
[_dataController reloadDataImmediatelyWithAnimationOptions:kASCollectionViewAnimationNone];
|
||||
[super reloadData];
|
||||
}
|
||||
@@ -800,7 +810,15 @@ static NSString * const kCellReuseIdentifier = @"_ASCollectionViewCell";
|
||||
|
||||
- (ASInterfaceState)interfaceStateForRangeController:(ASRangeController *)rangeController
|
||||
{
|
||||
return self.collectionNode.interfaceState;
|
||||
ASCollectionNode *collectionNode = self.collectionNode;
|
||||
if (collectionNode) {
|
||||
return self.collectionNode.interfaceState;
|
||||
} else {
|
||||
// Until we can always create an associated ASCollectionNode without a retain cycle,
|
||||
// we might be on our own to try to guess if we're visible. The node normally
|
||||
// handles this even if it is the root / directly added to the view hierarchy.
|
||||
return (self.window != nil ? ASInterfaceStateVisible : ASInterfaceStateNone);
|
||||
}
|
||||
}
|
||||
|
||||
- (NSArray *)rangeController:(ASRangeController *)rangeController nodesAtIndexPaths:(NSArray *)indexPaths
|
||||
@@ -824,7 +842,7 @@ static NSString * const kCellReuseIdentifier = @"_ASCollectionViewCell";
|
||||
- (void)rangeController:(ASRangeController *)rangeController didEndUpdatesAnimated:(BOOL)animated completion:(void (^)(BOOL))completion
|
||||
{
|
||||
ASDisplayNodeAssertMainThread();
|
||||
|
||||
|
||||
if (!self.asyncDataSource || _superIsPendingDataLoad) {
|
||||
if (completion) {
|
||||
completion(NO);
|
||||
@@ -847,7 +865,7 @@ static NSString * const kCellReuseIdentifier = @"_ASCollectionViewCell";
|
||||
- (void)rangeController:(ASRangeController *)rangeController didInsertNodes:(NSArray *)nodes atIndexPaths:(NSArray *)indexPaths withAnimationOptions:(ASDataControllerAnimationOptions)animationOptions
|
||||
{
|
||||
ASDisplayNodeAssertMainThread();
|
||||
|
||||
[_layoutFacilitator collectionViewEditingCellsAtIndexPaths:indexPaths];
|
||||
if (!self.asyncDataSource || _superIsPendingDataLoad) {
|
||||
return; // if the asyncDataSource has become invalid while we are processing, ignore this request to avoid crashes
|
||||
}
|
||||
@@ -866,7 +884,7 @@ static NSString * const kCellReuseIdentifier = @"_ASCollectionViewCell";
|
||||
- (void)rangeController:(ASRangeController *)rangeController didDeleteNodes:(NSArray *)nodes atIndexPaths:(NSArray *)indexPaths withAnimationOptions:(ASDataControllerAnimationOptions)animationOptions
|
||||
{
|
||||
ASDisplayNodeAssertMainThread();
|
||||
|
||||
[_layoutFacilitator collectionViewEditingCellsAtIndexPaths:indexPaths];
|
||||
if (!self.asyncDataSource || _superIsPendingDataLoad) {
|
||||
return; // if the asyncDataSource has become invalid while we are processing, ignore this request to avoid crashes
|
||||
}
|
||||
@@ -885,7 +903,7 @@ static NSString * const kCellReuseIdentifier = @"_ASCollectionViewCell";
|
||||
- (void)rangeController:(ASRangeController *)rangeController didInsertSectionsAtIndexSet:(NSIndexSet *)indexSet withAnimationOptions:(ASDataControllerAnimationOptions)animationOptions
|
||||
{
|
||||
ASDisplayNodeAssertMainThread();
|
||||
|
||||
[_layoutFacilitator collectionViewEditingSectionsAtIndexSet:indexSet];
|
||||
if (!self.asyncDataSource || _superIsPendingDataLoad) {
|
||||
return; // if the asyncDataSource has become invalid while we are processing, ignore this request to avoid crashes
|
||||
}
|
||||
@@ -904,7 +922,7 @@ static NSString * const kCellReuseIdentifier = @"_ASCollectionViewCell";
|
||||
- (void)rangeController:(ASRangeController *)rangeController didDeleteSectionsAtIndexSet:(NSIndexSet *)indexSet withAnimationOptions:(ASDataControllerAnimationOptions)animationOptions
|
||||
{
|
||||
ASDisplayNodeAssertMainThread();
|
||||
|
||||
[_layoutFacilitator collectionViewEditingSectionsAtIndexSet:indexSet];
|
||||
if (!self.asyncDataSource || _superIsPendingDataLoad) {
|
||||
return; // if the asyncDataSource has become invalid while we are processing, ignore this request to avoid crashes
|
||||
}
|
||||
|
||||
30
AsyncDisplayKit/ASCollectionViewLayoutFacilitatorProtocol.h
Normal file
30
AsyncDisplayKit/ASCollectionViewLayoutFacilitatorProtocol.h
Normal file
@@ -0,0 +1,30 @@
|
||||
/* Copyright (c) 2014-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*/
|
||||
|
||||
#ifndef ASCollectionViewLayoutFacilitatorProtocol_h
|
||||
#define ASCollectionViewLayoutFacilitatorProtocol_h
|
||||
|
||||
/**
|
||||
* This facilitator protocol is intended to help Layout to better
|
||||
* gel with the CollectionView
|
||||
*/
|
||||
@protocol ASCollectionViewLayoutFacilitatorProtocol <NSObject>
|
||||
|
||||
/**
|
||||
* Inform that the collectionView is editing the cells at a list of indexPaths
|
||||
*/
|
||||
- (void)collectionViewEditingCellsAtIndexPaths:(NSArray *)indexPaths;
|
||||
|
||||
/**
|
||||
* Inform that the collectionView is editing the sections at a set of indexes
|
||||
*/
|
||||
- (void)collectionViewEditingSectionsAtIndexSet:(NSIndexSet *)indexes;
|
||||
|
||||
@end
|
||||
|
||||
#endif /* ASCollectionViewLayoutFacilitatorProtocol_h */
|
||||
@@ -23,6 +23,12 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
#pragma mark - Configuration
|
||||
|
||||
/**
|
||||
@abstract Enable scrolling on the textView
|
||||
@default true
|
||||
*/
|
||||
@property (nonatomic) BOOL scrollEnabled;
|
||||
|
||||
/**
|
||||
@abstract Access to underlying UITextView for more configuration options.
|
||||
@warning This property should only be used on the main thread and should not be accessed before the editable text node's view is created.
|
||||
|
||||
@@ -16,16 +16,42 @@
|
||||
#import "ASTextNodeWordKerner.h"
|
||||
#import "ASThread.h"
|
||||
|
||||
//! @abstract This subclass exists solely to ensure the text view's panGestureRecognizer never begins, because it's sporadically enabled by UITextView. It will be removed pending rdar://14729288.
|
||||
@interface _ASDisabledPanUITextView : UITextView
|
||||
/**
|
||||
@abstract As originally reported in rdar://14729288, when scrollEnabled = NO,
|
||||
UITextView does not calculate its contentSize. This makes it difficult
|
||||
for a client to embed a UITextView inside a different scroll view with
|
||||
other content (setting scrollEnabled = NO on the UITextView itself,
|
||||
because the containing scroll view will handle the gesture)...
|
||||
because accessing contentSize is typically necessary to perform layout.
|
||||
Apple later closed the issue as expected behavior. This works around
|
||||
the issue by ensuring that contentSize is always calculated, while
|
||||
still providing control over the UITextView's scrolling.
|
||||
|
||||
See issue: https://github.com/facebook/AsyncDisplayKit/issues/1063
|
||||
*/
|
||||
@interface ASPanningOverriddenUITextView : UITextView
|
||||
{
|
||||
BOOL _shouldBlockPanGesture;
|
||||
}
|
||||
@end
|
||||
|
||||
@implementation _ASDisabledPanUITextView
|
||||
@implementation ASPanningOverriddenUITextView
|
||||
|
||||
- (BOOL)scrollEnabled
|
||||
{
|
||||
return _shouldBlockPanGesture;
|
||||
}
|
||||
|
||||
- (void)setScrollEnabled:(BOOL)scrollEnabled
|
||||
{
|
||||
_shouldBlockPanGesture = !scrollEnabled;
|
||||
[super setScrollEnabled:YES];
|
||||
}
|
||||
|
||||
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer
|
||||
{
|
||||
// Never allow our pans to begin.
|
||||
if (gestureRecognizer == self.panGestureRecognizer)
|
||||
// Never allow our pans to begin when _shouldBlockPanGesture is true.
|
||||
if (_shouldBlockPanGesture && gestureRecognizer == self.panGestureRecognizer)
|
||||
return NO;
|
||||
|
||||
// Otherwise, proceed as usual.
|
||||
@@ -207,11 +233,18 @@
|
||||
#pragma mark - Configuration
|
||||
@synthesize delegate = _delegate;
|
||||
|
||||
- (void)setScrollEnabled:(BOOL)scrollEnabled
|
||||
{
|
||||
ASDN::MutexLocker l(_textKitLock);
|
||||
_scrollEnabled = scrollEnabled;
|
||||
[_textKitComponents.textView setScrollEnabled:_scrollEnabled];
|
||||
}
|
||||
|
||||
- (UITextView *)textView
|
||||
{
|
||||
ASDisplayNodeAssertMainThread();
|
||||
if (!_textKitComponents.textView) {
|
||||
_textKitComponents.textView = [[_ASDisabledPanUITextView alloc] initWithFrame:CGRectZero textContainer:_textKitComponents.textContainer];
|
||||
_textKitComponents.textView = [[ASPanningOverriddenUITextView alloc] initWithFrame:CGRectZero textContainer:_textKitComponents.textContainer];
|
||||
}
|
||||
return _textKitComponents.textView;
|
||||
}
|
||||
|
||||
@@ -95,6 +95,16 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@optional
|
||||
|
||||
/**
|
||||
* Notification that the image node failed to download the image.
|
||||
*
|
||||
* @param imageNode The sender.
|
||||
* @param error The error with details.
|
||||
*
|
||||
* @discussion Called on a background queue.
|
||||
*/
|
||||
- (void)imageNode:(ASNetworkImageNode *)imageNode didFailWithError:(NSError *)error;
|
||||
|
||||
/**
|
||||
* Notification that the image node finished decoding an image.
|
||||
*
|
||||
|
||||
@@ -168,14 +168,14 @@
|
||||
_cacheUUID = nil;
|
||||
}
|
||||
|
||||
- (void)_downloadImageWithCompletion:(void (^)(CGImageRef))finished
|
||||
- (void)_downloadImageWithCompletion:(void (^)(CGImageRef, NSError*))finished
|
||||
{
|
||||
_imageDownload = [_downloader downloadImageWithURL:_URL
|
||||
callbackQueue:dispatch_get_main_queue()
|
||||
downloadProgressBlock:NULL
|
||||
completion:^(CGImageRef responseImage, NSError *error) {
|
||||
if (finished != NULL) {
|
||||
finished(responseImage);
|
||||
finished(responseImage, error);
|
||||
}
|
||||
}];
|
||||
}
|
||||
@@ -210,7 +210,7 @@
|
||||
}
|
||||
} else {
|
||||
__weak __typeof__(self) weakSelf = self;
|
||||
void (^finished)(CGImageRef) = ^(CGImageRef responseImage) {
|
||||
void (^finished)(CGImageRef, NSError *) = ^(CGImageRef responseImage, NSError *error) {
|
||||
__typeof__(self) strongSelf = weakSelf;
|
||||
if (strongSelf == nil) {
|
||||
return;
|
||||
@@ -232,6 +232,9 @@
|
||||
if (responseImage != NULL) {
|
||||
[strongSelf->_delegate imageNode:strongSelf didLoadImage:strongSelf.image];
|
||||
}
|
||||
else if (error && [strongSelf->_delegate respondsToSelector:@selector(imageNode:didFailWithError:)]) {
|
||||
[strongSelf->_delegate imageNode:strongSelf didFailWithError:error];
|
||||
}
|
||||
};
|
||||
|
||||
if (_cache != nil) {
|
||||
@@ -247,7 +250,7 @@
|
||||
if (image == NULL && _downloader != nil) {
|
||||
[self _downloadImageWithCompletion:finished];
|
||||
} else {
|
||||
finished(image);
|
||||
finished(image, NULL);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
{
|
||||
UICollectionViewFlowLayout *_flowLayout;
|
||||
ASPagerNodeProxy *_proxy;
|
||||
id <ASPagerNodeDataSource> _pagerDataSource;
|
||||
__weak id <ASPagerNodeDataSource> _pagerDataSource;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -34,7 +34,7 @@ static NSString * const kCellReuseIdentifier = @"_ASTableViewCell";
|
||||
@class _ASTableViewCell;
|
||||
|
||||
@protocol _ASTableViewCellDelegate <NSObject>
|
||||
- (void)willLayoutSubviewsOfTableViewCell:(_ASTableViewCell *)tableViewCell;
|
||||
- (void)didLayoutSubviewsOfTableViewCell:(_ASTableViewCell *)tableViewCell;
|
||||
@end
|
||||
|
||||
@interface _ASTableViewCell : UITableViewCell
|
||||
@@ -47,8 +47,8 @@ static NSString * const kCellReuseIdentifier = @"_ASTableViewCell";
|
||||
|
||||
- (void)layoutSubviews
|
||||
{
|
||||
[_delegate willLayoutSubviewsOfTableViewCell:self];
|
||||
[super layoutSubviews];
|
||||
[_delegate didLayoutSubviewsOfTableViewCell:self];
|
||||
}
|
||||
|
||||
- (void)didTransitionToState:(UITableViewCellStateMask)state
|
||||
@@ -722,7 +722,15 @@ static NSString * const kCellReuseIdentifier = @"_ASTableViewCell";
|
||||
|
||||
- (ASInterfaceState)interfaceStateForRangeController:(ASRangeController *)rangeController
|
||||
{
|
||||
return self.tableNode.interfaceState;
|
||||
ASTableNode *tableNode = self.tableNode;
|
||||
if (tableNode) {
|
||||
return self.tableNode.interfaceState;
|
||||
} else {
|
||||
// Until we can always create an associated ASTableNode without a retain cycle,
|
||||
// we might be on our own to try to guess if we're visible. The node normally
|
||||
// handles this even if it is the root / directly added to the view hierarchy.
|
||||
return (self.window != nil ? ASInterfaceStateVisible : ASInterfaceStateNone);
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - ASRangeControllerDelegate
|
||||
@@ -895,7 +903,7 @@ static NSString * const kCellReuseIdentifier = @"_ASTableViewCell";
|
||||
|
||||
#pragma mark - _ASTableViewCellDelegate
|
||||
|
||||
- (void)willLayoutSubviewsOfTableViewCell:(_ASTableViewCell *)tableViewCell
|
||||
- (void)didLayoutSubviewsOfTableViewCell:(_ASTableViewCell *)tableViewCell
|
||||
{
|
||||
CGFloat contentViewWidth = tableViewCell.contentView.bounds.size.width;
|
||||
ASCellNode *node = tableViewCell.node;
|
||||
|
||||
@@ -336,14 +336,14 @@ static NSArray *DefaultLinkAttributeNames = @[ NSLinkAttributeName ];
|
||||
|
||||
- (void)setAttributedString:(NSAttributedString *)attributedString
|
||||
{
|
||||
if (ASObjectIsEqual(attributedString, _attributedString)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (attributedString == nil) {
|
||||
attributedString = [[NSAttributedString alloc] initWithString:@"" attributes:nil];
|
||||
}
|
||||
|
||||
if (ASObjectIsEqual(attributedString, _attributedString)) {
|
||||
return;
|
||||
}
|
||||
|
||||
_attributedString = ASCleanseAttributedStringOfCoreTextAttributes(attributedString);
|
||||
|
||||
// Sync the truncation string with attributes from the updated _attributedString
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
#import "ASRangeController.h"
|
||||
|
||||
@interface ASCollectionView ()
|
||||
- (instancetype)_initWithFrame:(CGRect)frame collectionViewLayout:(UICollectionViewLayout *)layout ownedByNode:(BOOL)ownedByNode;
|
||||
- (instancetype)_initWithFrame:(CGRect)frame collectionViewLayout:(UICollectionViewLayout *)layout layoutFacilitator:(id<ASCollectionViewLayoutFacilitatorProtocol>)layoutFacilitator ownedByNode:(BOOL)ownedByNode;
|
||||
|
||||
@property (nonatomic, weak, readwrite) ASCollectionNode *collectionNode;
|
||||
@property (nonatomic, strong, readonly) ASRangeController *rangeController;
|
||||
|
||||
@@ -195,39 +195,6 @@ namespace ASDN {
|
||||
typedef Locker<StaticMutex> StaticMutexLocker;
|
||||
typedef Unlocker<StaticMutex> StaticMutexUnlocker;
|
||||
|
||||
struct SpinLock
|
||||
{
|
||||
SpinLock &operator= (bool value) {
|
||||
_l = value ? ~0 : 0; return *this;
|
||||
}
|
||||
|
||||
SpinLock() { _l = OS_SPINLOCK_INIT; }
|
||||
SpinLock(const SpinLock&) = delete;
|
||||
SpinLock &operator=(const SpinLock&) = delete;
|
||||
|
||||
bool try_lock () {
|
||||
return OSSpinLockTry (&_l);
|
||||
}
|
||||
|
||||
void lock () {
|
||||
OSSpinLockLock(&_l);
|
||||
}
|
||||
|
||||
void unlock () {
|
||||
OSSpinLockUnlock(&_l);
|
||||
}
|
||||
|
||||
OSSpinLock *spinlock () {
|
||||
return &_l;
|
||||
}
|
||||
|
||||
private:
|
||||
OSSpinLock _l;
|
||||
};
|
||||
|
||||
typedef Locker<SpinLock> SpinLocker;
|
||||
typedef Unlocker<SpinLock> SpinUnlocker;
|
||||
|
||||
struct Condition
|
||||
{
|
||||
Condition () {
|
||||
|
||||
@@ -111,7 +111,7 @@ static NSCharacterSet *_defaultAvoidTruncationCharacterSet()
|
||||
// to make sure our width calculations aren't being offset by glyphs going beyond the constrained rect.
|
||||
boundingRect = CGRectIntersection(boundingRect, {.size = constrainedRect.size});
|
||||
|
||||
_calculatedSize = [_shadower outsetSizeWithInsetSize:boundingRect.size];
|
||||
_calculatedSize = [_shadower outsetSizeWithInsetSize:CGSizeMake(boundingRect.size.width + boundingRect.origin.x, boundingRect.size.height + boundingRect.origin.y)];
|
||||
}
|
||||
|
||||
- (CGSize)size
|
||||
|
||||
@@ -2,9 +2,10 @@
|
||||
|
||||
[](https://travis-ci.org/facebook/AsyncDisplayKit)
|
||||
[](https://coveralls.io/r/facebook/AsyncDisplayKit?branch=master)
|
||||
[](http://cocoapods.org/?q=AsyncDisplayKit)
|
||||
[]()
|
||||
[](https://github.com/facebook/AsyncDisplayKit/blob/master/LICENSE)
|
||||
[](http://cocoapods.org/pods/AsyncDisplayKit)
|
||||
[]()
|
||||
[](https://github.com/facebook/AsyncDisplayKit/blob/master/LICENSE)
|
||||
[](http://cocoapods.org/pods/AsyncDisplayKit)
|
||||
|
||||
AsyncDisplayKit is an iOS framework that keeps even the most complex user
|
||||
interfaces smooth and responsive. It was originally built to make Facebook's
|
||||
|
||||
Reference in New Issue
Block a user