Merge remote-tracking branch 'facebook/master'

This commit is contained in:
Hannah Troisi
2016-03-28 10:42:35 -07:00
21 changed files with 2251 additions and 873 deletions

View File

@@ -1,11 +1,11 @@
Pod::Spec.new do |spec|
spec.name = 'AsyncDisplayKit'
spec.version = '1.9.7'
spec.version = '1.9.7.1'
spec.license = { :type => 'BSD' }
spec.homepage = 'http://asyncdisplaykit.org'
spec.authors = { 'Scott Goodson' => 'scottgoodson@gmail.com', 'Ryan Nystrom' => 'rnystrom@fb.com' }
spec.summary = 'Smooth asynchronous user interfaces for iOS apps.'
spec.source = { :git => 'https://github.com/facebook/AsyncDisplayKit.git', :tag => '1.9.7' }
spec.source = { :git => 'https://github.com/facebook/AsyncDisplayKit.git', :tag => '1.9.7.1' }
spec.documentation_url = 'http://asyncdisplaykit.org/appledoc/'
@@ -51,7 +51,7 @@ Pod::Spec.new do |spec|
spec.subspec 'PINRemoteImage' do |pin|
pin.xcconfig = { 'GCC_PREPROCESSOR_DEFINITIONS' => '$(inherited) PIN_REMOTE_IMAGE=1' }
pin.dependency 'PINRemoteImage/iOS', '>= 2.1'
pin.dependency 'PINRemoteImage/iOS', '>= 2.1.2'
pin.dependency 'AsyncDisplayKit/ASDealloc2MainObject'
end

View File

@@ -266,13 +266,13 @@
764D83D61C8EA515009B4FB8 /* AsyncDisplayKit+Debug.m in Sources */ = {isa = PBXBuildFile; fileRef = 764D83D31C8EA515009B4FB8 /* AsyncDisplayKit+Debug.m */; };
767E7F8D1C9019130066C000 /* AsyncDisplayKit+Debug.h in Headers */ = {isa = PBXBuildFile; fileRef = 764D83D21C8EA515009B4FB8 /* AsyncDisplayKit+Debug.h */; settings = {ATTRIBUTES = (Public, ); }; };
767E7F8E1C90191D0066C000 /* AsyncDisplayKit+Debug.m in Sources */ = {isa = PBXBuildFile; fileRef = 764D83D31C8EA515009B4FB8 /* AsyncDisplayKit+Debug.m */; };
81EE384F1C8E94F000456208 /* ASRunLoopQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 81EE384D1C8E94F000456208 /* ASRunLoopQueue.h */; settings = {ATTRIBUTES = (Public, ); }; };
81EE38501C8E94F000456208 /* ASRunLoopQueue.mm in Sources */ = {isa = PBXBuildFile; fileRef = 81EE384E1C8E94F000456208 /* ASRunLoopQueue.mm */; };
7A06A73A1C35F08800FE8DAA /* ASRelativeLayoutSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = 7A06A7381C35F08800FE8DAA /* ASRelativeLayoutSpec.mm */; };
7A06A73B1C35F08800FE8DAA /* ASRelativeLayoutSpec.h in Headers */ = {isa = PBXBuildFile; fileRef = 7A06A7391C35F08800FE8DAA /* ASRelativeLayoutSpec.h */; settings = {ATTRIBUTES = (Public, ); }; };
7AB338661C55B3420055FDE8 /* ASRelativeLayoutSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = 7A06A7381C35F08800FE8DAA /* ASRelativeLayoutSpec.mm */; };
7AB338671C55B3460055FDE8 /* ASRelativeLayoutSpec.h in Headers */ = {isa = PBXBuildFile; fileRef = 7A06A7391C35F08800FE8DAA /* ASRelativeLayoutSpec.h */; settings = {ATTRIBUTES = (Public, ); }; };
7AB338691C55B97B0055FDE8 /* ASRelativeLayoutSpecSnapshotTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 7AB338681C55B97B0055FDE8 /* ASRelativeLayoutSpecSnapshotTests.mm */; };
81EE384F1C8E94F000456208 /* ASRunLoopQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 81EE384D1C8E94F000456208 /* ASRunLoopQueue.h */; settings = {ATTRIBUTES = (Public, ); }; };
81EE38501C8E94F000456208 /* ASRunLoopQueue.mm in Sources */ = {isa = PBXBuildFile; fileRef = 81EE384E1C8E94F000456208 /* ASRunLoopQueue.mm */; };
92DD2FE31BF4B97E0074C9DD /* ASMapNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 92DD2FE11BF4B97E0074C9DD /* ASMapNode.h */; settings = {ATTRIBUTES = (Public, ); }; };
92DD2FE41BF4B97E0074C9DD /* ASMapNode.mm in Sources */ = {isa = PBXBuildFile; fileRef = 92DD2FE21BF4B97E0074C9DD /* ASMapNode.mm */; };
92DD2FE61BF4D05E0074C9DD /* MapKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 92DD2FE51BF4D05E0074C9DD /* MapKit.framework */; };
@@ -524,6 +524,8 @@
DECBD6EA1BE56E1900CF4905 /* ASButtonNode.mm in Sources */ = {isa = PBXBuildFile; fileRef = DECBD6E61BE56E1900CF4905 /* ASButtonNode.mm */; };
E52405B31C8FEF03004DC8E7 /* ASDisplayNodeLayoutContext.mm in Sources */ = {isa = PBXBuildFile; fileRef = E52405B21C8FEF03004DC8E7 /* ASDisplayNodeLayoutContext.mm */; };
E52405B51C8FEF16004DC8E7 /* ASDisplayNodeLayoutContext.h in Headers */ = {isa = PBXBuildFile; fileRef = E52405B41C8FEF16004DC8E7 /* ASDisplayNodeLayoutContext.h */; };
E55D86321CA8A14000A0C26F /* ASLayoutable.mm in Sources */ = {isa = PBXBuildFile; fileRef = E55D86311CA8A14000A0C26F /* ASLayoutable.mm */; };
E55D86331CA8A14000A0C26F /* ASLayoutable.mm in Sources */ = {isa = PBXBuildFile; fileRef = E55D86311CA8A14000A0C26F /* ASLayoutable.mm */; };
E5711A2B1C840C81009619D4 /* ASIndexedNodeContext.h in Headers */ = {isa = PBXBuildFile; fileRef = E5711A2A1C840C81009619D4 /* ASIndexedNodeContext.h */; settings = {ATTRIBUTES = (Public, ); }; };
E5711A2C1C840C81009619D4 /* ASIndexedNodeContext.h in Headers */ = {isa = PBXBuildFile; fileRef = E5711A2A1C840C81009619D4 /* ASIndexedNodeContext.h */; };
E5711A2E1C840C96009619D4 /* ASIndexedNodeContext.m in Sources */ = {isa = PBXBuildFile; fileRef = E5711A2D1C840C96009619D4 /* ASIndexedNodeContext.m */; };
@@ -742,11 +744,11 @@
6BDC61F51978FEA400E50D21 /* AsyncDisplayKit.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; path = AsyncDisplayKit.h; sourceTree = "<group>"; };
764D83D21C8EA515009B4FB8 /* AsyncDisplayKit+Debug.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "AsyncDisplayKit+Debug.h"; sourceTree = "<group>"; };
764D83D31C8EA515009B4FB8 /* AsyncDisplayKit+Debug.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "AsyncDisplayKit+Debug.m"; sourceTree = "<group>"; };
81EE384D1C8E94F000456208 /* ASRunLoopQueue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ASRunLoopQueue.h; path = ../ASRunLoopQueue.h; sourceTree = "<group>"; };
81EE384E1C8E94F000456208 /* ASRunLoopQueue.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = ASRunLoopQueue.mm; path = ../ASRunLoopQueue.mm; sourceTree = "<group>"; };
7A06A7381C35F08800FE8DAA /* ASRelativeLayoutSpec.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = ASRelativeLayoutSpec.mm; path = AsyncDisplayKit/Layout/ASRelativeLayoutSpec.mm; sourceTree = "<group>"; };
7A06A7391C35F08800FE8DAA /* ASRelativeLayoutSpec.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ASRelativeLayoutSpec.h; path = AsyncDisplayKit/Layout/ASRelativeLayoutSpec.h; sourceTree = "<group>"; };
7AB338681C55B97B0055FDE8 /* ASRelativeLayoutSpecSnapshotTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASRelativeLayoutSpecSnapshotTests.mm; sourceTree = "<group>"; };
81EE384D1C8E94F000456208 /* ASRunLoopQueue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ASRunLoopQueue.h; path = ../ASRunLoopQueue.h; sourceTree = "<group>"; };
81EE384E1C8E94F000456208 /* ASRunLoopQueue.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = ASRunLoopQueue.mm; path = ../ASRunLoopQueue.mm; sourceTree = "<group>"; };
92DD2FE11BF4B97E0074C9DD /* ASMapNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASMapNode.h; sourceTree = "<group>"; };
92DD2FE21BF4B97E0074C9DD /* ASMapNode.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASMapNode.mm; sourceTree = "<group>"; };
92DD2FE51BF4D05E0074C9DD /* MapKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MapKit.framework; path = System/Library/Frameworks/MapKit.framework; sourceTree = SDKROOT; };
@@ -808,7 +810,7 @@
ACF6ED471B17847A00DA7C62 /* ASStackPositionedLayout.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASStackPositionedLayout.h; sourceTree = "<group>"; };
ACF6ED481B17847A00DA7C62 /* ASStackPositionedLayout.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASStackPositionedLayout.mm; sourceTree = "<group>"; };
ACF6ED491B17847A00DA7C62 /* ASStackUnpositionedLayout.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASStackUnpositionedLayout.h; sourceTree = "<group>"; };
ACF6ED4A1B17847A00DA7C62 /* ASStackUnpositionedLayout.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; lineEnding = 0; path = ASStackUnpositionedLayout.mm; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
ACF6ED4A1B17847A00DA7C62 /* ASStackUnpositionedLayout.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; lineEnding = 0; path = ASStackUnpositionedLayout.mm; sourceTree = "<group>"; };
ACF6ED531B178DC700DA7C62 /* ASCenterLayoutSpecSnapshotTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASCenterLayoutSpecSnapshotTests.mm; sourceTree = "<group>"; };
ACF6ED541B178DC700DA7C62 /* ASDimensionTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASDimensionTests.mm; sourceTree = "<group>"; };
ACF6ED551B178DC700DA7C62 /* ASInsetLayoutSpecSnapshotTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASInsetLayoutSpecSnapshotTests.mm; sourceTree = "<group>"; };
@@ -860,6 +862,7 @@
DECBD6E61BE56E1900CF4905 /* ASButtonNode.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASButtonNode.mm; sourceTree = "<group>"; };
E52405B21C8FEF03004DC8E7 /* ASDisplayNodeLayoutContext.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASDisplayNodeLayoutContext.mm; sourceTree = "<group>"; };
E52405B41C8FEF16004DC8E7 /* ASDisplayNodeLayoutContext.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASDisplayNodeLayoutContext.h; sourceTree = "<group>"; };
E55D86311CA8A14000A0C26F /* ASLayoutable.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = ASLayoutable.mm; path = AsyncDisplayKit/Layout/ASLayoutable.mm; sourceTree = "<group>"; };
E5711A2A1C840C81009619D4 /* ASIndexedNodeContext.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASIndexedNodeContext.h; sourceTree = "<group>"; };
E5711A2D1C840C96009619D4 /* ASIndexedNodeContext.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASIndexedNodeContext.m; sourceTree = "<group>"; };
EFA731F0396842FF8AB635EE /* libPods-AsyncDisplayKitTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-AsyncDisplayKitTests.a"; sourceTree = BUILT_PRODUCTS_DIR; };
@@ -1318,6 +1321,7 @@
ACF6ED0B1B17843500DA7C62 /* ASLayout.h */,
ACF6ED0C1B17843500DA7C62 /* ASLayout.mm */,
ACF6ED111B17843500DA7C62 /* ASLayoutable.h */,
E55D86311CA8A14000A0C26F /* ASLayoutable.mm */,
9CDC18CB1B910E12004965E2 /* ASLayoutablePrivate.h */,
ACF6ED0D1B17843500DA7C62 /* ASLayoutSpec.h */,
ACF6ED0E1B17843500DA7C62 /* ASLayoutSpec.mm */,
@@ -1862,6 +1866,7 @@
buildActionMask = 2147483647;
files = (
058D0A22195D050800B7D73C /* _ASAsyncTransaction.mm in Sources */,
E55D86321CA8A14000A0C26F /* ASLayoutable.mm in Sources */,
058D0A23195D050800B7D73C /* _ASAsyncTransactionContainer.m in Sources */,
058D0A24195D050800B7D73C /* _ASAsyncTransactionGroup.m in Sources */,
DBDB83961C6E879900D0098C /* ASPagerFlowLayout.m in Sources */,
@@ -2037,6 +2042,7 @@
AC47D9421B3B891B00AAEE9D /* ASCellNode.m in Sources */,
34EFC7641B701CC600AD841F /* ASCenterLayoutSpec.mm in Sources */,
18C2ED831B9B7DE800F627B3 /* ASCollectionNode.mm in Sources */,
E55D86331CA8A14000A0C26F /* ASLayoutable.mm in Sources */,
B35061F61B010EFD0018CF92 /* ASCollectionView.mm in Sources */,
509E68641B3AEDB7009B9150 /* ASCollectionViewLayoutController.mm in Sources */,
B35061F91B010EFD0018CF92 /* ASControlNode.mm in Sources */,
@@ -2090,7 +2096,6 @@
9C8221981BA237B80037F19A /* ASStackBaselinePositionedLayout.mm in Sources */,
34EFC7721B701D0300AD841F /* ASStackLayoutSpec.mm in Sources */,
34EFC7761B701D2A00AD841F /* ASStackPositionedLayout.mm in Sources */,
DECC2ED01C35C1C600388446 /* ASRangeControllerBeta.mm in Sources */,
7AB338661C55B3420055FDE8 /* ASRelativeLayoutSpec.mm in Sources */,
34EFC7781B701D3100AD841F /* ASStackUnpositionedLayout.mm in Sources */,
DE84918E1C8FFF9F003D89E9 /* ASRunLoopQueue.mm in Sources */,

View File

@@ -66,12 +66,12 @@ typedef NS_ENUM(NSUInteger, ASCellNodeVisibilityEvent) {
//@property (atomic, retain) UIColor *backgroundColor;
@property (nonatomic) UITableViewCellSelectionStyle selectionStyle;
/*
/**
* A Boolean value that indicates whether the node is selected.
*/
@property (nonatomic, assign) BOOL selected;
/*
/**
* A Boolean value that indicates whether the node is highlighted.
*/
@property (nonatomic, assign) BOOL highlighted;

View File

@@ -9,6 +9,8 @@
#import "ASControlNode.h"
#import "ASControlNode+Subclasses.h"
#import "ASThread.h"
#import "ASDisplayNodeExtras.h"
#import "ASImageNode.h"
// UIControl allows dragging some distance outside of the control itself during
// tracking. This value depends on the device idiom (25 or 70 points), so
@@ -73,7 +75,7 @@ static BOOL _enableHitTestDebug = NO;
@implementation ASControlNode
{
ASDisplayNode *_debugHighlightOverlay;
ASImageNode *_debugHighlightOverlay;
}
#pragma mark - Lifecycle
@@ -251,10 +253,10 @@ static BOOL _enableHitTestDebug = NO;
// add a highlight overlay node with area of ASControlNode + UIEdgeInsets
self.clipsToBounds = NO;
_debugHighlightOverlay = [[ASDisplayNode alloc] init];
_debugHighlightOverlay = [[ASImageNode alloc] init];
_debugHighlightOverlay.zPosition = 1000; // CALayer doesn't have -moveSublayerToFront, but this will ensure we're over the top of any siblings.
_debugHighlightOverlay.layerBacked = YES;
_debugHighlightOverlay.backgroundColor = [[UIColor greenColor] colorWithAlphaComponent:0.5];
_debugHighlightOverlay.backgroundColor = [[UIColor greenColor] colorWithAlphaComponent:0.4];
[self addSubnode:_debugHighlightOverlay];
}
}
@@ -461,12 +463,35 @@ void _ASEnumerateControlEventsIncludedInMaskWithBlock(ASControlNodeEvent mask, v
[super layout];
if (_debugHighlightOverlay) {
UIEdgeInsets insets = [self hitTestSlop];
CGRect controlNodeRect = self.bounds;
_debugHighlightOverlay.frame = CGRectMake(controlNodeRect.origin.x + insets.left,
controlNodeRect.origin.y + insets.top,
controlNodeRect.size.width - insets.left - insets.right,
controlNodeRect.size.height - insets.top - insets.bottom);
// Even if our parents don't have clipsToBounds set and would allow us to display the debug overlay, UIKit event delivery (hitTest:)
// will not search sub-hierarchies if one of our parents does not return YES for pointInside:. In such a scenario, hitTestSlop
// may not be able to expand the tap target as much as desired without also setting some hitTestSlop on the limiting parents.
CGRect intersectRect = UIEdgeInsetsInsetRect(self.bounds, [self hitTestSlop]);
CALayer *layer = self.layer;
CALayer *intersectLayer = layer;
CALayer *intersectSuperlayer = layer.superlayer;
// Stop climbing if we encounter a UIScrollView, as its offset bounds origin may make it seem like our events will be clipped when
// scrolling will actually reveal them (because this process will not re-run due to scrolling)
while (intersectSuperlayer && ![intersectSuperlayer.delegate respondsToSelector:@selector(contentOffset)]) {
// Get our parent's tappable bounds. If the parent has an associated node, consider hitTestSlop, as it will extend its pointInside:.
CGRect parentHitRect = intersectSuperlayer.bounds;
ASDisplayNode *parentNode = ASLayerToDisplayNode(intersectSuperlayer);
if (parentNode) {
parentHitRect = UIEdgeInsetsInsetRect(parentHitRect, [parentNode hitTestSlop]);
}
// Convert our current rectangle to parent coordinates, and intersect with the parent's hit rect.
CGRect intersectRectInParentCoordinates = [intersectSuperlayer convertRect:intersectRect fromLayer:intersectLayer];
intersectRect = CGRectIntersection(parentHitRect, intersectRectInParentCoordinates);
// Advance up the tree.
intersectLayer = intersectSuperlayer;
intersectSuperlayer = intersectLayer.superlayer;
}
_debugHighlightOverlay.frame = [intersectLayer convertRect:intersectRect toLayer:layer];
}
}
@@ -475,5 +500,4 @@ void _ASEnumerateControlEventsIncludedInMaskWithBlock(ASControlNodeEvent mask, v
_enableHitTestDebug = enable;
}
@end

View File

@@ -337,9 +337,9 @@ static ASDisplayNodeMethodOverrides GetASDisplayNodeMethodOverrides(Class c)
- (void)dealloc
{
ASDisplayNodeAssertMainThread();
// Synchronous nodes may not be able to call the hierarchy notifications, so only enforce for regular nodes.
ASDisplayNodeAssert(_flags.synchronous || !ASInterfaceStateIncludesVisible(_interfaceState), @"Node should always be marked invisible before deallocating; interfaceState: %lu, %@", (unsigned long)_interfaceState, self);
self.interfaceState &= ~ASInterfaceStateVisible;
self.asyncLayer.asyncDelegate = nil;
_view.asyncdisplaykit_node = nil;
_layer.asyncdisplaykit_node = nil;
@@ -630,7 +630,8 @@ static ASDisplayNodeMethodOverrides GetASDisplayNodeMethodOverrides(Class c)
return NO;
}
if (ASHierarchyStateIncludesLayoutPending(_hierarchyState) && constrainedSize.transitionID != _pendingTransitionID) {
if (ASHierarchyStateIncludesLayoutPending(_hierarchyState)
&& _pendingTransitionID != ASLayoutableGetCurrentContext().transitionID) {
return NO;
}
@@ -668,8 +669,7 @@ static ASDisplayNodeMethodOverrides GetASDisplayNodeMethodOverrides(Class c)
}
int32_t transitionID = [self _newTransitionID];
constrainedSize.transitionID = transitionID;
ASDisplayNodePerformBlockOnEverySubnode(self, ^(ASDisplayNode * _Nonnull node) {
ASDisplayNodeAssert([node _hasTransitionsInProgress] == NO, @"Can't start a transition when one of the subnodes is performing one.");
node.hierarchyState |= ASHierarchyStateLayoutPending;
@@ -679,6 +679,8 @@ static ASDisplayNodeMethodOverrides GetASDisplayNodeMethodOverrides(Class c)
void (^transitionBlock)() = ^{
ASLayout *newLayout;
{
ASLayoutableSetCurrentContext(ASLayoutableContextMake(transitionID, NO));
ASDN::MutexLocker l(_propertyLock);
BOOL disableImplicitHierarchyManagement = self.usesImplicitHierarchyManagement == NO;
self.usesImplicitHierarchyManagement = YES; // Temporary flag for 1.9.x
@@ -686,6 +688,8 @@ static ASDisplayNodeMethodOverrides GetASDisplayNodeMethodOverrides(Class c)
if (disableImplicitHierarchyManagement) {
self.usesImplicitHierarchyManagement = NO; // Temporary flag for 1.9.x
}
ASLayoutableClearCurrentContext();
}
if ([self _shouldAbortTransitionWithID:transitionID]) {
@@ -829,7 +833,7 @@ static ASDisplayNodeMethodOverrides GetASDisplayNodeMethodOverrides(Class c)
- (BOOL)_displaysAsynchronously
{
ASDisplayNodeAssertThreadAffinity(self);
return self.isSynchronous == NO && _flags.displaysAsynchronously;
return _flags.synchronous == NO && _flags.displaysAsynchronously;
}
- (void)setDisplaysAsynchronously:(BOOL)displaysAsynchronously
@@ -1545,10 +1549,11 @@ static NSInteger incrementIfFound(NSInteger i) {
// Profiling has shown that locking this method is beneficial, so each of the property accesses don't have to lock and unlock.
ASDN::MutexLocker l(_propertyLock);
if (!self.inHierarchy && !_flags.visibilityNotificationsDisabled && ![self __selfOrParentHasVisibilityNotificationsDisabled]) {
self.inHierarchy = YES;
if (!_flags.isInHierarchy && !_flags.visibilityNotificationsDisabled && ![self __selfOrParentHasVisibilityNotificationsDisabled]) {
_flags.isEnteringHierarchy = YES;
if (self.shouldRasterizeDescendants) {
_flags.isInHierarchy = YES;
if (_flags.shouldRasterizeDescendants) {
// Nodes that are descendants of a rasterized container do not have views or layers, and so cannot receive visibility notifications directly via orderIn/orderOut CALayer actions. Manually send visibility notifications to rasterized descendants.
[self _recursiveWillEnterHierarchy];
} else {
@@ -1568,7 +1573,7 @@ static NSInteger incrementIfFound(NSInteger i) {
[self _setupPlaceholderLayerIfNeeded];
_placeholderLayer.opacity = 1.0;
[CATransaction commit];
[self.layer addSublayer:_placeholderLayer];
[layer addSublayer:_placeholderLayer];
}
}
}
@@ -1582,18 +1587,34 @@ static NSInteger incrementIfFound(NSInteger i) {
// Profiling has shown that locking this method is beneficial, so each of the property accesses don't have to lock and unlock.
ASDN::MutexLocker l(_propertyLock);
if (self.inHierarchy && !_flags.visibilityNotificationsDisabled && ![self __selfOrParentHasVisibilityNotificationsDisabled]) {
self.inHierarchy = NO;
if (_flags.isInHierarchy && !_flags.visibilityNotificationsDisabled && ![self __selfOrParentHasVisibilityNotificationsDisabled]) {
_flags.isExitingHierarchy = YES;
_flags.isInHierarchy = NO;
[self.asyncLayer cancelAsyncDisplay];
_flags.isExitingHierarchy = YES;
if (self.shouldRasterizeDescendants) {
if (_flags.shouldRasterizeDescendants) {
// Nodes that are descendants of a rasterized container do not have views or layers, and so cannot receive visibility notifications directly via orderIn/orderOut CALayer actions. Manually send visibility notifications to rasterized descendants.
[self _recursiveDidExitHierarchy];
} else {
[self didExitHierarchy];
}
// This case is important when tearing down hierarchies. We must deliver a visibilityDidChange:NO callback, as part our API guarantee that this method can be used for
// things like data analytics about user content viewing. We cannot call the method in the dealloc as any incidental retain operations in client code would fail.
// Additionally, it may be that a Standard UIView which is containing us is moving between hierarchies, and we should not send the call if we will be re-added in the
// same runloop. Strategy: strong reference (might be the last!), wait one runloop, and confirm we are still outside the hierarchy (both layer-backed and view-backed).
// TODO: This approach could be optimized by only performing the dispatch for root elements + recursively apply the interface state change. This would require a closer
// integration with _ASDisplayLayer to ensure that the superlayer pointer has been cleared by this stage (to check if we are root or not), or a different delegate call.
if (ASInterfaceStateIncludesVisible(_interfaceState)) {
dispatch_async(dispatch_get_main_queue(), ^{
ASDN::MutexLocker l(_propertyLock);
if (!_flags.isInHierarchy && ASInterfaceStateIncludesVisible(_interfaceState)) {
self.interfaceState = (_interfaceState & ~ASInterfaceStateVisible);
}
});
}
[self didExitHierarchy];
_flags.isExitingHierarchy = NO;
}
}
@@ -1719,7 +1740,7 @@ static NSInteger incrementIfFound(NSInteger i) {
// Helper method to summarize whether or not the node run through the display process
- (BOOL)__implementsDisplay
{
return _flags.implementsDrawRect || _flags.implementsImageDisplay || self.shouldRasterizeDescendants || _flags.implementsInstanceDrawRect || _flags.implementsInstanceImageDisplay;
return _flags.implementsDrawRect || _flags.implementsImageDisplay || _flags.shouldRasterizeDescendants || _flags.implementsInstanceDrawRect || _flags.implementsInstanceImageDisplay;
}
- (BOOL)placeholderShouldPersist

View File

@@ -18,7 +18,7 @@ NS_ASSUME_NONNULL_BEGIN
*/
@interface ASEditableTextNode : ASDisplayNode
// @abstract The text node's delegate, which must conform to the <ASEditableTextNodeDelegate> protocol.
//! @abstract The text node's delegate, which must conform to the <ASEditableTextNodeDelegate> protocol.
@property (nonatomic, readwrite, weak) id <ASEditableTextNodeDelegate> delegate;
#pragma mark - Configuration
@@ -66,12 +66,12 @@ NS_ASSUME_NONNULL_BEGIN
//! @abstract The text input mode used by the receiver's keyboard, if it is visible. This value is undefined if the receiver is not the first responder.
@property (nonatomic, readonly) UITextInputMode *textInputMode;
/*
/**
@abstract The textContainerInset of both the placeholder and typed textView. This value defaults to UIEdgeInsetsZero.
*/
@property (nonatomic, readwrite) UIEdgeInsets textContainerInset;
/*
/**
@abstract The returnKeyType of the keyboard. This value defaults to UIReturnKeyDefault.
*/
@property (nonatomic, readwrite) UIReturnKeyType returnKeyType;

View File

@@ -98,6 +98,7 @@
return nil;
_displayingPlaceholder = YES;
_scrollEnabled = YES;
// Create the scaffolding for the text view.
_textKitComponents = [ASTextKitComponents componentsWithAttributedSeedString:nil textContainerSize:CGSizeZero];
@@ -161,7 +162,7 @@
// Create and configure our text view.
_textKitComponents.textView = self.textView;
//_textKitComponents.textView = NO; // Unfortunately there's a bug here with iOS 7 DP5 that causes the text-view to only be one line high when scrollEnabled is NO. rdar://14729288
_textKitComponents.textView.scrollEnabled = _scrollEnabled;
_textKitComponents.textView.delegate = self;
#if TARGET_OS_IOS
_textKitComponents.textView.editable = YES;

View File

@@ -100,12 +100,6 @@
_cropDisplayBounds = CGRectNull;
_placeholderColor = ASDisplayNodeDefaultPlaceholderColor();
if ([ASImageNode shouldShowImageScalingOverlay]) {
_debugLabelNode = [[ASTextNode alloc] init];
_debugLabelNode.layerBacked = YES;
[self addSubnode:_debugLabelNode];
}
return self;
}
@@ -144,6 +138,14 @@
[self invalidateCalculatedLayout];
if (image) {
[self setNeedsDisplay];
if ([ASImageNode shouldShowImageScalingOverlay]) {
ASPerformBlockOnMainThread(^{
_debugLabelNode = [[ASTextNode alloc] init];
_debugLabelNode.layerBacked = YES;
[self addSubnode:_debugLabelNode];
});
}
} else {
self.contents = nil;
}

View File

@@ -25,10 +25,8 @@
- (CGPoint)targetContentOffsetForProposedContentOffset:(CGPoint)proposedContentOffset
{
if (self.currentIndexPath) {
CGPoint contentOffset = [self _targetContentOffsetForItemAtIndexPath:self.currentIndexPath
proposedContentOffset:proposedContentOffset];
self.currentIndexPath = nil;
return contentOffset;
return [self _targetContentOffsetForItemAtIndexPath:self.currentIndexPath
proposedContentOffset:proposedContentOffset];
}
return [super targetContentOffsetForProposedContentOffset:proposedContentOffset];
@@ -36,6 +34,9 @@
- (CGPoint)_targetContentOffsetForItemAtIndexPath:(NSIndexPath *)indexPath proposedContentOffset:(CGPoint)proposedContentOffset
{
if ([self _dataSourceIsEmpty]) {
return proposedContentOffset;
}
UICollectionViewLayoutAttributes *attributes = [self layoutAttributesForItemAtIndexPath:indexPath];
CGFloat xOffset = (self.collectionView.bounds.size.width - attributes.frame.size.width) / 2;
return CGPointMake(attributes.frame.origin.x - xOffset, proposedContentOffset.y);
@@ -54,6 +55,11 @@
return nil;
}
- (BOOL)_dataSourceIsEmpty
{
return ([self.collectionView numberOfSections] == 0 || [self.collectionView numberOfItemsInSection:0] == 0);
}
- (CGRect)_visibleRect
{
CGRect visibleRect;

View File

@@ -38,7 +38,7 @@ typedef void (^ASDataControllerCompletionBlock)(NSArray<ASCellNode *> *nodes, NS
*/
- (void)batchLayoutNodesFromContexts:(NSArray<ASIndexedNodeContext *> *)contexts ofKind:(NSString *)kind completion:(ASDataControllerCompletionBlock)completionBlock;
/*
/**
* Perform measurement and layout of loaded nodes on the main thread, skipping unloaded nodes.
*
* @discussion Once nodes have loaded their views, we can't layout in the background so this is a chance

View File

@@ -90,6 +90,11 @@
self.keepalive_node = _node;
}
else if (currentSuperview && !newSuperview) {
// Clearing keepalive_node may cause deallocation of the node. In this case, __exitHierarchy may not have an opportunity (e.g. _node will be cleared
// by the time -didMoveToWindow occurs after this) to clear the Visible interfaceState, which we need to do before deallocation to meet an API guarantee.
if (_node.inHierarchy) {
[_node __exitHierarchy];
}
self.keepalive_node = nil;
}

View File

@@ -30,7 +30,6 @@ typedef struct {
typedef struct {
CGSize min;
CGSize max;
int32_t transitionID;
} ASSizeRange;
extern ASRelativeDimension const ASRelativeDimensionUnconstrained;

View File

@@ -0,0 +1,40 @@
//
// ASLayoutablePrivate.mm
// AsyncDisplayKit
//
// Created by Huy Nguyen on 3/27/16.
// Copyright © 2016 Facebook. All rights reserved.
//
#import "ASLayoutablePrivate.h"
#import "pthread.h"
#import <map>
ASLayoutableContext ASLayoutableContextMake(int32_t transitionID, BOOL needsVisualizeNode)
{
struct ASLayoutableContext context;
context.transitionID = transitionID;
context.needsVisualizeNode = needsVisualizeNode;
return context;
}
static std::map<mach_port_t, ASLayoutableContext> layoutableContextMap;
static inline mach_port_t ASLayoutableGetCurrentContextKey()
{
return pthread_mach_thread_np(pthread_self());
}
void ASLayoutableSetCurrentContext(struct ASLayoutableContext context)
{
layoutableContextMap[ASLayoutableGetCurrentContextKey()] = context;
}
struct ASLayoutableContext ASLayoutableGetCurrentContext()
{
return layoutableContextMap[ASLayoutableGetCurrentContextKey()];
}
void ASLayoutableClearCurrentContext() {
layoutableContextMap.erase(ASLayoutableGetCurrentContextKey());
}

View File

@@ -14,6 +14,19 @@
@class ASLayoutOptions;
@protocol ASLayoutable;
struct ASLayoutableContext {
int32_t transitionID;
BOOL needsVisualizeNode;
};
extern struct ASLayoutableContext ASLayoutableContextMake(int32_t transitionID, BOOL needsVisualizeNode);
extern void ASLayoutableSetCurrentContext(struct ASLayoutableContext context);
extern struct ASLayoutableContext ASLayoutableGetCurrentContext();
extern void ASLayoutableClearCurrentContext();
/**
* The base protocol for ASLayoutable. Generally the methods/properties in this class do not need to be
* called by the end user and are only called internally. However, there may be a case where the methods are useful.

View File

@@ -58,7 +58,7 @@
@property (nonatomic, assign, readonly) CGFloat currentScaleFactor;
#pragma mark - Drawing
/*
/**
Draw the renderer's text content into the bounds provided.
@param bounds The rect in which to draw the contents of the renderer.
@@ -67,20 +67,20 @@
#pragma mark - Layout
/*
/**
Returns the computed size of the renderer given the constrained size and other parameters in the initializer.
*/
- (CGSize)size;
#pragma mark - Text Ranges
/*
/**
The character range from the original attributedString that is displayed by the renderer given the parameters in the
initializer.
*/
- (std::vector<NSRange>)visibleRanges;
/*
/**
The number of lines shown in the string.
*/
- (NSUInteger)lineCount;

View File

@@ -189,9 +189,10 @@ static NSCharacterSet *_defaultAvoidTruncationCharacterSet()
// We add an assertion so we can track the rare conditions where a graphics context is not present
ASDisplayNodeAssertNotNil(context, @"This is no good without a context.");
// This renderer may not be the one that did the sizing. If that is the case its _currentScaleFactor will not be set, so we should compute it now
if (_sizeIsCalculated == NO && isinf(_constrainedSize.width) == NO && [_attributes.pointSizeScaleFactors count] > 0) {
_currentScaleFactor = [[self fontSizeAdjuster] scaleFactor];
// This renderer may not be the one that did the sizing. If that is the case its truncation and currentScaleFactor may not have been evaluated.
// If there's any possibility we need to truncate or scale (e.g. width is not infinite, perform the size calculation.
if (_sizeIsCalculated == NO && isinf(_constrainedSize.width) == NO) {
[self _calculateSize];
}
CGRect shadowInsetBounds = [[self shadower] insetRectWithConstrainedRect:bounds];

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "group:Sample.xcodeproj">
</FileRef>
<FileRef
location = "group:Pods/Pods.xcodeproj">
</FileRef>
</Workspace>

View File

@@ -17,6 +17,10 @@
@interface ViewController () <ASEditableTextNodeDelegate>
{
ASEditableTextNode *_textNode;
// These elements are a test case for ASTextNode truncation.
UILabel *_label;
ASTextNode *_node;
}
@end
@@ -44,6 +48,24 @@
// the usual delegate methods are available; see ASEditableTextNodeDelegate
_textNode.delegate = self;
// Do any additional setup after loading the view, typically from a nib.
NSDictionary *attrs = @{ NSFontAttributeName: [UIFont fontWithName:@"HelveticaNeue" size:12.0f] };
NSAttributedString *string = [[NSAttributedString alloc] initWithString:@"1\n2\n3\n4\n5" attributes:attrs];
_label = [[UILabel alloc] init];
_label.attributedText = string;
_label.backgroundColor = [UIColor lightGrayColor];
_label.numberOfLines = 3;
_label.frame = CGRectMake(20, 400, 40, 100);
_node = [[ASTextNode alloc] init];
_node.maximumNumberOfLines = 3;
_node.backgroundColor = [UIColor lightGrayColor];
_node.attributedString = string;
_node.frame = CGRectMake(70, 400, 40, 100);
// [_node measure:CGSizeMake(40, 50)]; No longer needed now that https://github.com/facebook/AsyncDisplayKit/issues/1295 is fixed.
return self;
}
@@ -53,6 +75,8 @@
[super viewDidLoad];
[self.view addSubnode:_textNode];
[self.view addSubnode:_node];
[self.view addSubview:_label];
[self.view addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tap:)]];
}

File diff suppressed because it is too large Load Diff

View File

@@ -89,6 +89,7 @@
_postNode.userInteractionEnabled = YES;
_postNode.linkAttributeNames = @[ kLinkAttributeName ];
_postNode.attributedString = attrString;
_postNode.passthroughNonlinkTouches = YES; // passes touches through when they aren't on a link
}