Merge branch 'master' into ASVideoNode

This commit is contained in:
Luke Parham
2016-01-23 14:11:33 -06:00
21 changed files with 197 additions and 70 deletions

View File

@@ -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;

View File

@@ -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>

View File

@@ -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);

View File

@@ -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;

View 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

View File

@@ -8,6 +8,8 @@
#import <AsyncDisplayKit/ASCollectionView.h>
@protocol ASCollectionViewLayoutFacilitatorProtocol;
NS_ASSUME_NONNULL_BEGIN
/**

View File

@@ -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]) {

View File

@@ -19,6 +19,7 @@
@protocol ASCollectionDataSource;
@protocol ASCollectionDelegate;
@protocol ASCollectionViewLayoutInspecting;
@protocol ASCollectionViewLayoutFacilitatorProtocol;
NS_ASSUME_NONNULL_BEGIN

View File

@@ -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
}

View 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 */

View File

@@ -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.

View File

@@ -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;
}

View File

@@ -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.
*

View File

@@ -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);
}
};

View File

@@ -15,7 +15,7 @@
{
UICollectionViewFlowLayout *_flowLayout;
ASPagerNodeProxy *_proxy;
id <ASPagerNodeDataSource> _pagerDataSource;
__weak id <ASPagerNodeDataSource> _pagerDataSource;
}
@end

View File

@@ -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;

View File

@@ -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

View File

@@ -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;

View File

@@ -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 () {

View File

@@ -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

View File

@@ -2,9 +2,10 @@
[![Build Status](https://travis-ci.org/facebook/AsyncDisplayKit.svg)](https://travis-ci.org/facebook/AsyncDisplayKit)
[![Coverage Status](https://coveralls.io/repos/facebook/AsyncDisplayKit/badge.svg?branch=master)](https://coveralls.io/r/facebook/AsyncDisplayKit?branch=master)
[![Version](http://img.shields.io/cocoapods/v/AsyncDisplayKit.svg)](http://cocoapods.org/?q=AsyncDisplayKit)
[![Platform](http://img.shields.io/cocoapods/p/AsyncDisplayKit.svg)]()
[![License](http://img.shields.io/cocoapods/l/AsyncDisplayKit.svg)](https://github.com/facebook/AsyncDisplayKit/blob/master/LICENSE)
[![Version](https://img.shields.io/cocoapods/v/AsyncDisplayKit.svg)](http://cocoapods.org/pods/AsyncDisplayKit)
[![Platform](https://img.shields.io/cocoapods/p/AsyncDisplayKit.svg)]()
[![License](https://img.shields.io/cocoapods/l/AsyncDisplayKit.svg)](https://github.com/facebook/AsyncDisplayKit/blob/master/LICENSE)
[![Downloads](https://img.shields.io/badge/downloads-%3E120k-green.svg)](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