From abe98d5b09b37a70a406a2c8b5e07fb9bcfe66f6 Mon Sep 17 00:00:00 2001 From: Huy Nguyen Date: Thu, 28 May 2015 20:36:55 +0300 Subject: [PATCH] Integrate new layout nodes to the framework. - Introduce ASLayoutNode and its subclasses. - ASDisplayNode measures its ASLayoutNode and cache the result (ASLayout). Calculated size and position of each subnode can be retrieved from the calculated layout. - Custom nodes need to override -layoutNodeThatFits:(CGSize) instead of -calculateSizeThatFits:(CGSize). - Custom nodes do not need to layout its subnodes (in -layout:) anymore. ASDisplayNode can handle the job most of the time, by walking through its layout tree. - ASCompositeNode is used to embed (display) subnodes to a node's layout. That way, each subnode will also be measured while the parent node is measuring. And the parent node knows where its subnodes are within its layout. --- AsyncDisplayKit.podspec | 1 + AsyncDisplayKit.xcodeproj/project.pbxproj | 162 ++++++++++++++++-- .../{ASCellNode.m => ASCellNode.mm} | 25 +-- AsyncDisplayKit/ASDisplayNode+Subclasses.h | 31 ++-- AsyncDisplayKit/ASDisplayNode.h | 16 +- AsyncDisplayKit/ASDisplayNode.mm | 127 ++++++++------ AsyncDisplayKit/ASEditableTextNode.mm | 13 +- AsyncDisplayKit/ASImageNode.mm | 15 +- AsyncDisplayKit/ASTextNode.mm | 15 +- AsyncDisplayKit/AsyncDisplayKit.h | 13 ++ .../Details/ASHighlightOverlayLayer.mm | 4 +- .../Private/ASDisplayNodeInternal.h | 5 +- Base/ASAssert.h | 7 + 13 files changed, 315 insertions(+), 119 deletions(-) rename AsyncDisplayKit/{ASCellNode.m => ASCellNode.mm} (80%) diff --git a/AsyncDisplayKit.podspec b/AsyncDisplayKit.podspec index 5acc730b53..daa77e83e1 100644 --- a/AsyncDisplayKit.podspec +++ b/AsyncDisplayKit.podspec @@ -12,6 +12,7 @@ Pod::Spec.new do |spec| spec.public_header_files = [ 'AsyncDisplayKit/*.h', 'AsyncDisplayKit/Details/**/*.h', + 'AsyncDisplayKit/Layout/*.h', 'Base/*.h' ] diff --git a/AsyncDisplayKit.xcodeproj/project.pbxproj b/AsyncDisplayKit.xcodeproj/project.pbxproj index 19168c3652..be28785168 100644 --- a/AsyncDisplayKit.xcodeproj/project.pbxproj +++ b/AsyncDisplayKit.xcodeproj/project.pbxproj @@ -26,7 +26,6 @@ 055F1A3819ABD413004DAFF1 /* ASRangeController.h in Headers */ = {isa = PBXBuildFile; fileRef = 055F1A3619ABD413004DAFF1 /* ASRangeController.h */; settings = {ATTRIBUTES = (Public, ); }; }; 055F1A3919ABD413004DAFF1 /* ASRangeController.mm in Sources */ = {isa = PBXBuildFile; fileRef = 055F1A3719ABD413004DAFF1 /* ASRangeController.mm */; }; 055F1A3C19ABD43F004DAFF1 /* ASCellNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 055F1A3A19ABD43F004DAFF1 /* ASCellNode.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 055F1A3D19ABD43F004DAFF1 /* ASCellNode.m in Sources */ = {isa = PBXBuildFile; fileRef = 055F1A3B19ABD43F004DAFF1 /* ASCellNode.m */; }; 056D21551ABCEF50001107EF /* ASImageNodeSnapshotTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 056D21541ABCEF50001107EF /* ASImageNodeSnapshotTests.m */; }; 0574D5E219C110940097DC25 /* ASTableViewProtocols.h in Headers */ = {isa = PBXBuildFile; fileRef = 0574D5E119C110610097DC25 /* ASTableViewProtocols.h */; settings = {ATTRIBUTES = (Public, ); }; }; 057D02C41AC0A66700C7AC3C /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 057D02C31AC0A66700C7AC3C /* main.m */; }; @@ -189,7 +188,6 @@ B31A241E1B0114FD0016AE7A /* AsyncDisplayKit.h in Headers */ = {isa = PBXBuildFile; fileRef = 6BDC61F51978FEA400E50D21 /* AsyncDisplayKit.h */; settings = {ATTRIBUTES = (Public, ); }; }; B35061DF1B010EDF0018CF92 /* AsyncDisplayKit-iOS.h in Headers */ = {isa = PBXBuildFile; fileRef = B35061DE1B010EDF0018CF92 /* AsyncDisplayKit-iOS.h */; settings = {ATTRIBUTES = (Public, ); }; }; B35061F31B010EFD0018CF92 /* ASCellNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 055F1A3A19ABD43F004DAFF1 /* ASCellNode.h */; settings = {ATTRIBUTES = (Public, ); }; }; - B35061F41B010EFD0018CF92 /* ASCellNode.m in Sources */ = {isa = PBXBuildFile; fileRef = 055F1A3B19ABD43F004DAFF1 /* ASCellNode.m */; }; 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 */; }; B35061F71B010EFD0018CF92 /* ASCollectionViewProtocols.h in Headers */ = {isa = PBXBuildFile; fileRef = AC3C4A531A113EEC00143C57 /* ASCollectionViewProtocols.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -297,6 +295,40 @@ B350625D1B0111740018CF92 /* Photos.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 051943141A1575670030A7D0 /* Photos.framework */; }; B350625E1B0111780018CF92 /* AssetsLibrary.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 051943121A1575630030A7D0 /* AssetsLibrary.framework */; }; B350625F1B0111800018CF92 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 058D09AF195D04C000B7D73C /* Foundation.framework */; }; + AC6456091B0A335000CF11B8 /* ASCellNode.mm in Sources */ = {isa = PBXBuildFile; fileRef = AC6456071B0A335000CF11B8 /* ASCellNode.mm */; }; + ACF6ED1A1B17843500DA7C62 /* ASBackgroundLayoutNode.h in Headers */ = {isa = PBXBuildFile; fileRef = ACF6ED011B17843500DA7C62 /* ASBackgroundLayoutNode.h */; }; + ACF6ED1B1B17843500DA7C62 /* ASBackgroundLayoutNode.mm in Sources */ = {isa = PBXBuildFile; fileRef = ACF6ED021B17843500DA7C62 /* ASBackgroundLayoutNode.mm */; }; + ACF6ED1C1B17843500DA7C62 /* ASCenterLayoutNode.h in Headers */ = {isa = PBXBuildFile; fileRef = ACF6ED031B17843500DA7C62 /* ASCenterLayoutNode.h */; }; + ACF6ED1D1B17843500DA7C62 /* ASCenterLayoutNode.mm in Sources */ = {isa = PBXBuildFile; fileRef = ACF6ED041B17843500DA7C62 /* ASCenterLayoutNode.mm */; }; + ACF6ED1E1B17843500DA7C62 /* ASCompositeNode.h in Headers */ = {isa = PBXBuildFile; fileRef = ACF6ED051B17843500DA7C62 /* ASCompositeNode.h */; }; + ACF6ED1F1B17843500DA7C62 /* ASCompositeNode.mm in Sources */ = {isa = PBXBuildFile; fileRef = ACF6ED061B17843500DA7C62 /* ASCompositeNode.mm */; }; + ACF6ED201B17843500DA7C62 /* ASDimension.h in Headers */ = {isa = PBXBuildFile; fileRef = ACF6ED071B17843500DA7C62 /* ASDimension.h */; }; + ACF6ED211B17843500DA7C62 /* ASDimension.mm in Sources */ = {isa = PBXBuildFile; fileRef = ACF6ED081B17843500DA7C62 /* ASDimension.mm */; }; + ACF6ED221B17843500DA7C62 /* ASInsetLayoutNode.h in Headers */ = {isa = PBXBuildFile; fileRef = ACF6ED091B17843500DA7C62 /* ASInsetLayoutNode.h */; }; + ACF6ED231B17843500DA7C62 /* ASInsetLayoutNode.mm in Sources */ = {isa = PBXBuildFile; fileRef = ACF6ED0A1B17843500DA7C62 /* ASInsetLayoutNode.mm */; }; + ACF6ED241B17843500DA7C62 /* ASLayout.h in Headers */ = {isa = PBXBuildFile; fileRef = ACF6ED0B1B17843500DA7C62 /* ASLayout.h */; }; + ACF6ED251B17843500DA7C62 /* ASLayout.mm in Sources */ = {isa = PBXBuildFile; fileRef = ACF6ED0C1B17843500DA7C62 /* ASLayout.mm */; }; + ACF6ED261B17843500DA7C62 /* ASLayoutNode.h in Headers */ = {isa = PBXBuildFile; fileRef = ACF6ED0D1B17843500DA7C62 /* ASLayoutNode.h */; }; + ACF6ED271B17843500DA7C62 /* ASLayoutNode.mm in Sources */ = {isa = PBXBuildFile; fileRef = ACF6ED0E1B17843500DA7C62 /* ASLayoutNode.mm */; }; + ACF6ED281B17843500DA7C62 /* ASLayoutNodeSize.h in Headers */ = {isa = PBXBuildFile; fileRef = ACF6ED0F1B17843500DA7C62 /* ASLayoutNodeSize.h */; }; + ACF6ED291B17843500DA7C62 /* ASLayoutNodeSize.mm in Sources */ = {isa = PBXBuildFile; fileRef = ACF6ED101B17843500DA7C62 /* ASLayoutNodeSize.mm */; }; + ACF6ED2A1B17843500DA7C62 /* ASLayoutNodeSubclass.h in Headers */ = {isa = PBXBuildFile; fileRef = ACF6ED111B17843500DA7C62 /* ASLayoutNodeSubclass.h */; }; + ACF6ED2B1B17843500DA7C62 /* ASOverlayLayoutNode.h in Headers */ = {isa = PBXBuildFile; fileRef = ACF6ED121B17843500DA7C62 /* ASOverlayLayoutNode.h */; }; + ACF6ED2C1B17843500DA7C62 /* ASOverlayLayoutNode.mm in Sources */ = {isa = PBXBuildFile; fileRef = ACF6ED131B17843500DA7C62 /* ASOverlayLayoutNode.mm */; }; + ACF6ED2D1B17843500DA7C62 /* ASRatioLayoutNode.h in Headers */ = {isa = PBXBuildFile; fileRef = ACF6ED141B17843500DA7C62 /* ASRatioLayoutNode.h */; }; + ACF6ED2E1B17843500DA7C62 /* ASRatioLayoutNode.mm in Sources */ = {isa = PBXBuildFile; fileRef = ACF6ED151B17843500DA7C62 /* ASRatioLayoutNode.mm */; }; + ACF6ED2F1B17843500DA7C62 /* ASStackLayoutNode.h in Headers */ = {isa = PBXBuildFile; fileRef = ACF6ED161B17843500DA7C62 /* ASStackLayoutNode.h */; }; + ACF6ED301B17843500DA7C62 /* ASStackLayoutNode.mm in Sources */ = {isa = PBXBuildFile; fileRef = ACF6ED171B17843500DA7C62 /* ASStackLayoutNode.mm */; }; + ACF6ED311B17843500DA7C62 /* ASStaticLayoutNode.h in Headers */ = {isa = PBXBuildFile; fileRef = ACF6ED181B17843500DA7C62 /* ASStaticLayoutNode.h */; }; + ACF6ED321B17843500DA7C62 /* ASStaticLayoutNode.mm in Sources */ = {isa = PBXBuildFile; fileRef = ACF6ED191B17843500DA7C62 /* ASStaticLayoutNode.mm */; }; + ACF6ED4B1B17847A00DA7C62 /* ASInternalHelpers.h in Headers */ = {isa = PBXBuildFile; fileRef = ACF6ED431B17847A00DA7C62 /* ASInternalHelpers.h */; }; + ACF6ED4C1B17847A00DA7C62 /* ASInternalHelpers.mm in Sources */ = {isa = PBXBuildFile; fileRef = ACF6ED441B17847A00DA7C62 /* ASInternalHelpers.mm */; }; + ACF6ED4D1B17847A00DA7C62 /* ASLayoutNodeUtilities.h in Headers */ = {isa = PBXBuildFile; fileRef = ACF6ED451B17847A00DA7C62 /* ASLayoutNodeUtilities.h */; }; + ACF6ED4E1B17847A00DA7C62 /* ASStackLayoutNodeUtilities.h in Headers */ = {isa = PBXBuildFile; fileRef = ACF6ED461B17847A00DA7C62 /* ASStackLayoutNodeUtilities.h */; }; + ACF6ED4F1B17847A00DA7C62 /* ASStackPositionedLayout.h in Headers */ = {isa = PBXBuildFile; fileRef = ACF6ED471B17847A00DA7C62 /* ASStackPositionedLayout.h */; }; + ACF6ED501B17847A00DA7C62 /* ASStackPositionedLayout.mm in Sources */ = {isa = PBXBuildFile; fileRef = ACF6ED481B17847A00DA7C62 /* ASStackPositionedLayout.mm */; }; + ACF6ED511B17847A00DA7C62 /* ASStackUnpositionedLayout.h in Headers */ = {isa = PBXBuildFile; fileRef = ACF6ED491B17847A00DA7C62 /* ASStackUnpositionedLayout.h */; }; + ACF6ED521B17847A00DA7C62 /* ASStackUnpositionedLayout.mm in Sources */ = {isa = PBXBuildFile; fileRef = ACF6ED4A1B17847A00DA7C62 /* ASStackUnpositionedLayout.mm */; }; D785F6621A74327E00291744 /* ASScrollNode.h in Headers */ = {isa = PBXBuildFile; fileRef = D785F6601A74327E00291744 /* ASScrollNode.h */; settings = {ATTRIBUTES = (Public, ); }; }; D785F6631A74327E00291744 /* ASScrollNode.m in Sources */ = {isa = PBXBuildFile; fileRef = D785F6611A74327E00291744 /* ASScrollNode.m */; }; DB7121BCD50849C498C886FB /* libPods-AsyncDisplayKitTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = EFA731F0396842FF8AB635EE /* libPods-AsyncDisplayKitTests.a */; }; @@ -349,7 +381,6 @@ 055F1A3619ABD413004DAFF1 /* ASRangeController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASRangeController.h; sourceTree = ""; }; 055F1A3719ABD413004DAFF1 /* ASRangeController.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASRangeController.mm; sourceTree = ""; }; 055F1A3A19ABD43F004DAFF1 /* ASCellNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASCellNode.h; sourceTree = ""; }; - 055F1A3B19ABD43F004DAFF1 /* ASCellNode.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASCellNode.m; sourceTree = ""; }; 056D21501ABCEDA1001107EF /* ASSnapshotTestCase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASSnapshotTestCase.h; sourceTree = ""; }; 056D21541ABCEF50001107EF /* ASImageNodeSnapshotTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASImageNodeSnapshotTests.m; sourceTree = ""; }; 0574D5E119C110610097DC25 /* ASTableViewProtocols.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ASTableViewProtocols.h; sourceTree = ""; }; @@ -359,7 +390,7 @@ 057D02C51AC0A66700C7AC3C /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 057D02C61AC0A66700C7AC3C /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 0587F9BB1A7309ED00AFF0BA /* ASEditableTextNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASEditableTextNode.h; sourceTree = ""; }; - 0587F9BC1A7309ED00AFF0BA /* ASEditableTextNode.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASEditableTextNode.mm; sourceTree = ""; }; + 0587F9BC1A7309ED00AFF0BA /* ASEditableTextNode.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; lineEnding = 0; path = ASEditableTextNode.mm; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; 058D09AC195D04C000B7D73C /* libAsyncDisplayKit.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libAsyncDisplayKit.a; sourceTree = BUILT_PRODUCTS_DIR; }; 058D09AF195D04C000B7D73C /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; 058D09B3195D04C000B7D73C /* AsyncDisplayKit-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "AsyncDisplayKit-Prefix.pch"; sourceTree = ""; }; @@ -372,14 +403,14 @@ 058D09D6195D050800B7D73C /* ASControlNode.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASControlNode.m; sourceTree = ""; }; 058D09D7195D050800B7D73C /* ASControlNode+Subclasses.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "ASControlNode+Subclasses.h"; sourceTree = ""; }; 058D09D8195D050800B7D73C /* ASDisplayNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASDisplayNode.h; sourceTree = ""; }; - 058D09D9195D050800B7D73C /* ASDisplayNode.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASDisplayNode.mm; sourceTree = ""; }; - 058D09DA195D050800B7D73C /* ASDisplayNode+Subclasses.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "ASDisplayNode+Subclasses.h"; sourceTree = ""; }; + 058D09D9195D050800B7D73C /* ASDisplayNode.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; lineEnding = 0; path = ASDisplayNode.mm; sourceTree = ""; }; + 058D09DA195D050800B7D73C /* ASDisplayNode+Subclasses.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = "ASDisplayNode+Subclasses.h"; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; 058D09DB195D050800B7D73C /* ASDisplayNodeExtras.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASDisplayNodeExtras.h; sourceTree = ""; }; 058D09DC195D050800B7D73C /* ASDisplayNodeExtras.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASDisplayNodeExtras.mm; sourceTree = ""; }; 058D09DD195D050800B7D73C /* ASImageNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASImageNode.h; sourceTree = ""; }; - 058D09DE195D050800B7D73C /* ASImageNode.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASImageNode.mm; sourceTree = ""; }; + 058D09DE195D050800B7D73C /* ASImageNode.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; lineEnding = 0; path = ASImageNode.mm; sourceTree = ""; }; 058D09DF195D050800B7D73C /* ASTextNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASTextNode.h; sourceTree = ""; }; - 058D09E0195D050800B7D73C /* ASTextNode.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASTextNode.mm; sourceTree = ""; }; + 058D09E0195D050800B7D73C /* ASTextNode.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; lineEnding = 0; path = ASTextNode.mm; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; 058D09E2195D050800B7D73C /* _ASDisplayLayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = _ASDisplayLayer.h; sourceTree = ""; }; 058D09E3195D050800B7D73C /* _ASDisplayLayer.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = _ASDisplayLayer.mm; sourceTree = ""; }; 058D09E4195D050800B7D73C /* _ASDisplayView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = _ASDisplayView.h; sourceTree = ""; }; @@ -486,6 +517,40 @@ 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; path = Info.plist; sourceTree = ""; }; B35061DE1B010EDF0018CF92 /* AsyncDisplayKit-iOS.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "AsyncDisplayKit-iOS.h"; sourceTree = ""; }; + AC6456071B0A335000CF11B8 /* ASCellNode.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASCellNode.mm; sourceTree = ""; }; + ACF6ED011B17843500DA7C62 /* ASBackgroundLayoutNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ASBackgroundLayoutNode.h; path = AsyncDisplayKit/Layout/ASBackgroundLayoutNode.h; sourceTree = ""; }; + ACF6ED021B17843500DA7C62 /* ASBackgroundLayoutNode.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = ASBackgroundLayoutNode.mm; path = AsyncDisplayKit/Layout/ASBackgroundLayoutNode.mm; sourceTree = ""; }; + ACF6ED031B17843500DA7C62 /* ASCenterLayoutNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ASCenterLayoutNode.h; path = AsyncDisplayKit/Layout/ASCenterLayoutNode.h; sourceTree = ""; }; + ACF6ED041B17843500DA7C62 /* ASCenterLayoutNode.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = ASCenterLayoutNode.mm; path = AsyncDisplayKit/Layout/ASCenterLayoutNode.mm; sourceTree = ""; }; + ACF6ED051B17843500DA7C62 /* ASCompositeNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ASCompositeNode.h; path = AsyncDisplayKit/Layout/ASCompositeNode.h; sourceTree = ""; }; + ACF6ED061B17843500DA7C62 /* ASCompositeNode.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = ASCompositeNode.mm; path = AsyncDisplayKit/Layout/ASCompositeNode.mm; sourceTree = ""; }; + ACF6ED071B17843500DA7C62 /* ASDimension.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ASDimension.h; path = AsyncDisplayKit/Layout/ASDimension.h; sourceTree = ""; }; + ACF6ED081B17843500DA7C62 /* ASDimension.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = ASDimension.mm; path = AsyncDisplayKit/Layout/ASDimension.mm; sourceTree = ""; }; + ACF6ED091B17843500DA7C62 /* ASInsetLayoutNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ASInsetLayoutNode.h; path = AsyncDisplayKit/Layout/ASInsetLayoutNode.h; sourceTree = ""; }; + ACF6ED0A1B17843500DA7C62 /* ASInsetLayoutNode.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = ASInsetLayoutNode.mm; path = AsyncDisplayKit/Layout/ASInsetLayoutNode.mm; sourceTree = ""; }; + ACF6ED0B1B17843500DA7C62 /* ASLayout.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ASLayout.h; path = AsyncDisplayKit/Layout/ASLayout.h; sourceTree = ""; }; + ACF6ED0C1B17843500DA7C62 /* ASLayout.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = ASLayout.mm; path = AsyncDisplayKit/Layout/ASLayout.mm; sourceTree = ""; }; + ACF6ED0D1B17843500DA7C62 /* ASLayoutNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ASLayoutNode.h; path = AsyncDisplayKit/Layout/ASLayoutNode.h; sourceTree = ""; }; + ACF6ED0E1B17843500DA7C62 /* ASLayoutNode.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = ASLayoutNode.mm; path = AsyncDisplayKit/Layout/ASLayoutNode.mm; sourceTree = ""; }; + ACF6ED0F1B17843500DA7C62 /* ASLayoutNodeSize.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ASLayoutNodeSize.h; path = AsyncDisplayKit/Layout/ASLayoutNodeSize.h; sourceTree = ""; }; + ACF6ED101B17843500DA7C62 /* ASLayoutNodeSize.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = ASLayoutNodeSize.mm; path = AsyncDisplayKit/Layout/ASLayoutNodeSize.mm; sourceTree = ""; }; + ACF6ED111B17843500DA7C62 /* ASLayoutNodeSubclass.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ASLayoutNodeSubclass.h; path = AsyncDisplayKit/Layout/ASLayoutNodeSubclass.h; sourceTree = ""; }; + ACF6ED121B17843500DA7C62 /* ASOverlayLayoutNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ASOverlayLayoutNode.h; path = AsyncDisplayKit/Layout/ASOverlayLayoutNode.h; sourceTree = ""; }; + ACF6ED131B17843500DA7C62 /* ASOverlayLayoutNode.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = ASOverlayLayoutNode.mm; path = AsyncDisplayKit/Layout/ASOverlayLayoutNode.mm; sourceTree = ""; }; + ACF6ED141B17843500DA7C62 /* ASRatioLayoutNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ASRatioLayoutNode.h; path = AsyncDisplayKit/Layout/ASRatioLayoutNode.h; sourceTree = ""; }; + ACF6ED151B17843500DA7C62 /* ASRatioLayoutNode.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = ASRatioLayoutNode.mm; path = AsyncDisplayKit/Layout/ASRatioLayoutNode.mm; sourceTree = ""; }; + ACF6ED161B17843500DA7C62 /* ASStackLayoutNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ASStackLayoutNode.h; path = AsyncDisplayKit/Layout/ASStackLayoutNode.h; sourceTree = ""; }; + ACF6ED171B17843500DA7C62 /* ASStackLayoutNode.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = ASStackLayoutNode.mm; path = AsyncDisplayKit/Layout/ASStackLayoutNode.mm; sourceTree = ""; }; + ACF6ED181B17843500DA7C62 /* ASStaticLayoutNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ASStaticLayoutNode.h; path = AsyncDisplayKit/Layout/ASStaticLayoutNode.h; sourceTree = ""; }; + ACF6ED191B17843500DA7C62 /* ASStaticLayoutNode.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = ASStaticLayoutNode.mm; path = AsyncDisplayKit/Layout/ASStaticLayoutNode.mm; sourceTree = ""; }; + ACF6ED431B17847A00DA7C62 /* ASInternalHelpers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASInternalHelpers.h; sourceTree = ""; }; + ACF6ED441B17847A00DA7C62 /* ASInternalHelpers.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASInternalHelpers.mm; sourceTree = ""; }; + ACF6ED451B17847A00DA7C62 /* ASLayoutNodeUtilities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASLayoutNodeUtilities.h; sourceTree = ""; }; + ACF6ED461B17847A00DA7C62 /* ASStackLayoutNodeUtilities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASStackLayoutNodeUtilities.h; sourceTree = ""; }; + ACF6ED471B17847A00DA7C62 /* ASStackPositionedLayout.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASStackPositionedLayout.h; sourceTree = ""; }; + ACF6ED481B17847A00DA7C62 /* ASStackPositionedLayout.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASStackPositionedLayout.mm; sourceTree = ""; }; + ACF6ED491B17847A00DA7C62 /* ASStackUnpositionedLayout.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASStackUnpositionedLayout.h; sourceTree = ""; }; + ACF6ED4A1B17847A00DA7C62 /* ASStackUnpositionedLayout.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASStackUnpositionedLayout.mm; sourceTree = ""; }; D3779BCFF841AD3EB56537ED /* Pods-AsyncDisplayKitTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-AsyncDisplayKitTests.release.xcconfig"; path = "Pods/Target Support Files/Pods-AsyncDisplayKitTests/Pods-AsyncDisplayKitTests.release.xcconfig"; sourceTree = ""; }; D785F6601A74327E00291744 /* ASScrollNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASScrollNode.h; sourceTree = ""; }; D785F6611A74327E00291744 /* ASScrollNode.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASScrollNode.m; sourceTree = ""; }; @@ -599,7 +664,7 @@ isa = PBXGroup; children = ( 055F1A3A19ABD43F004DAFF1 /* ASCellNode.h */, - 055F1A3B19ABD43F004DAFF1 /* ASCellNode.m */, + AC6456071B0A335000CF11B8 /* ASCellNode.mm */, AC3C4A4F1A1139C100143C57 /* ASCollectionView.h */, AC3C4A501A1139C100143C57 /* ASCollectionView.mm */, AC3C4A531A113EEC00143C57 /* ASCollectionViewProtocols.h */, @@ -629,6 +694,7 @@ 6BDC61F51978FEA400E50D21 /* AsyncDisplayKit.h */, 058D09E1195D050800B7D73C /* Details */, 058D0A01195D050800B7D73C /* Private */, + AC6456051B0A333200CF11B8 /* Layout */, 058D09B2195D04C000B7D73C /* Supporting Files */, ); path = AsyncDisplayKit; @@ -781,6 +847,14 @@ 058D0A0E195D050800B7D73C /* ASImageNode+CGExtras.m */, 058D0A10195D050800B7D73C /* ASSentinel.h */, 058D0A11195D050800B7D73C /* ASSentinel.m */, + ACF6ED431B17847A00DA7C62 /* ASInternalHelpers.h */, + ACF6ED441B17847A00DA7C62 /* ASInternalHelpers.mm */, + ACF6ED451B17847A00DA7C62 /* ASLayoutNodeUtilities.h */, + ACF6ED461B17847A00DA7C62 /* ASStackLayoutNodeUtilities.h */, + ACF6ED471B17847A00DA7C62 /* ASStackPositionedLayout.h */, + ACF6ED481B17847A00DA7C62 /* ASStackPositionedLayout.mm */, + ACF6ED491B17847A00DA7C62 /* ASStackUnpositionedLayout.h */, + ACF6ED4A1B17847A00DA7C62 /* ASStackUnpositionedLayout.mm */, ); path = Private; sourceTree = ""; @@ -814,6 +888,39 @@ B35061DD1B010EDF0018CF92 /* Info.plist */, ); name = "Supporting Files"; + sourceTree = ""; + }; + AC6456051B0A333200CF11B8 /* Layout */ = { + isa = PBXGroup; + children = ( + ACF6ED011B17843500DA7C62 /* ASBackgroundLayoutNode.h */, + ACF6ED021B17843500DA7C62 /* ASBackgroundLayoutNode.mm */, + ACF6ED031B17843500DA7C62 /* ASCenterLayoutNode.h */, + ACF6ED041B17843500DA7C62 /* ASCenterLayoutNode.mm */, + ACF6ED051B17843500DA7C62 /* ASCompositeNode.h */, + ACF6ED061B17843500DA7C62 /* ASCompositeNode.mm */, + ACF6ED071B17843500DA7C62 /* ASDimension.h */, + ACF6ED081B17843500DA7C62 /* ASDimension.mm */, + ACF6ED091B17843500DA7C62 /* ASInsetLayoutNode.h */, + ACF6ED0A1B17843500DA7C62 /* ASInsetLayoutNode.mm */, + ACF6ED0B1B17843500DA7C62 /* ASLayout.h */, + ACF6ED0C1B17843500DA7C62 /* ASLayout.mm */, + ACF6ED0D1B17843500DA7C62 /* ASLayoutNode.h */, + ACF6ED0E1B17843500DA7C62 /* ASLayoutNode.mm */, + ACF6ED0F1B17843500DA7C62 /* ASLayoutNodeSize.h */, + ACF6ED101B17843500DA7C62 /* ASLayoutNodeSize.mm */, + ACF6ED111B17843500DA7C62 /* ASLayoutNodeSubclass.h */, + ACF6ED121B17843500DA7C62 /* ASOverlayLayoutNode.h */, + ACF6ED131B17843500DA7C62 /* ASOverlayLayoutNode.mm */, + ACF6ED141B17843500DA7C62 /* ASRatioLayoutNode.h */, + ACF6ED151B17843500DA7C62 /* ASRatioLayoutNode.mm */, + ACF6ED161B17843500DA7C62 /* ASStackLayoutNode.h */, + ACF6ED171B17843500DA7C62 /* ASStackLayoutNode.mm */, + ACF6ED181B17843500DA7C62 /* ASStaticLayoutNode.h */, + ACF6ED191B17843500DA7C62 /* ASStaticLayoutNode.mm */, + ); + name = Layout; + path = ..; sourceTree = ""; }; FD40E2760492F0CAAEAD552D /* Pods */ = { @@ -834,6 +941,7 @@ files = ( 291B63FB1AA53A7A000A71B3 /* ASScrollDirection.h in Headers */, 464052221A3F83C40061C0BA /* ASFlowLayoutController.h in Headers */, + ACF6ED1A1B17843500DA7C62 /* ASBackgroundLayoutNode.h in Headers */, 464052241A3F83C40061C0BA /* ASLayoutController.h in Headers */, 464052201A3F83C40061C0BA /* ASDataController.h in Headers */, 05A6D05A19D0EB64002DD95E /* ASDealloc2MainObject.h in Headers */, @@ -844,9 +952,12 @@ 058D0A4A195D05CB00B7D73C /* ASDisplayNode.h in Headers */, 1950C4491A3BB5C1005C8279 /* ASEqualityHelpers.h in Headers */, 058D0A4B195D05CB00B7D73C /* ASDisplayNode.mm in Headers */, + ACF6ED4B1B17847A00DA7C62 /* ASInternalHelpers.h in Headers */, + ACF6ED281B17843500DA7C62 /* ASLayoutNodeSize.h in Headers */, 058D0A4C195D05CB00B7D73C /* ASDisplayNode+Subclasses.h in Headers */, 058D0A4D195D05CB00B7D73C /* ASDisplayNodeExtras.h in Headers */, 058D0A4E195D05CB00B7D73C /* ASDisplayNodeExtras.mm in Headers */, + ACF6ED511B17847A00DA7C62 /* ASStackUnpositionedLayout.h in Headers */, 058D0A4F195D05CB00B7D73C /* ASImageNode.h in Headers */, 058D0A50195D05CB00B7D73C /* ASImageNode.mm in Headers */, 058D0A51195D05CB00B7D73C /* ASTextNode.h in Headers */, @@ -862,6 +973,7 @@ 058D0A55195D05DC00B7D73C /* _ASDisplayView.h in Headers */, 058D0A56195D05DC00B7D73C /* _ASDisplayView.mm in Headers */, 058D0A57195D05DC00B7D73C /* ASHighlightOverlayLayer.h in Headers */, + ACF6ED2D1B17843500DA7C62 /* ASRatioLayoutNode.h in Headers */, 058D0A58195D05DC00B7D73C /* ASHighlightOverlayLayer.mm in Headers */, 058D0A59195D05DC00B7D73C /* ASMutableAttributedStringBuilder.h in Headers */, 058D0A5A195D05DC00B7D73C /* ASMutableAttributedStringBuilder.m in Headers */, @@ -875,37 +987,47 @@ 058D0A61195D05DC00B7D73C /* ASTextNodeTextKitHelpers.h in Headers */, 058D0A62195D05DC00B7D73C /* ASTextNodeTextKitHelpers.mm in Headers */, 058D0A63195D05DC00B7D73C /* ASTextNodeTypes.h in Headers */, + ACF6ED261B17843500DA7C62 /* ASLayoutNode.h in Headers */, 292C599F1A956527007E5DD6 /* ASLayoutRangeType.h in Headers */, 464052251A3F83C40061C0BA /* ASMultidimensionalArrayUtils.h in Headers */, + ACF6ED221B17843500DA7C62 /* ASInsetLayoutNode.h in Headers */, 058D0A64195D05DC00B7D73C /* ASTextNodeWordKerner.h in Headers */, 299DA1A91A828D2900162D41 /* ASBatchContext.h in Headers */, 058D0A65195D05DC00B7D73C /* ASTextNodeWordKerner.m in Headers */, 058D0A66195D05DC00B7D73C /* NSMutableAttributedString+TextKitAdditions.h in Headers */, + ACF6ED201B17843500DA7C62 /* ASDimension.h in Headers */, 058D0A67195D05DC00B7D73C /* NSMutableAttributedString+TextKitAdditions.m in Headers */, 058D0A68195D05EC00B7D73C /* _ASAsyncTransaction.h in Headers */, 205F0E0F1B371875007741D0 /* UICollectionViewLayout+ASConvenience.h in Headers */, 058D0A69195D05EC00B7D73C /* _ASAsyncTransaction.m in Headers */, 058D0A6A195D05EC00B7D73C /* _ASAsyncTransactionContainer+Private.h in Headers */, + ACF6ED2B1B17843500DA7C62 /* ASOverlayLayoutNode.h in Headers */, 058D0A6B195D05EC00B7D73C /* _ASAsyncTransactionContainer.h in Headers */, 058D0A6C195D05EC00B7D73C /* _ASAsyncTransactionContainer.m in Headers */, + ACF6ED1C1B17843500DA7C62 /* ASCenterLayoutNode.h in Headers */, 6BDC61F61979037800E50D21 /* AsyncDisplayKit.h in Headers */, 058D0A6D195D05EC00B7D73C /* _ASAsyncTransactionGroup.h in Headers */, 058D0A6E195D05EC00B7D73C /* _ASAsyncTransactionGroup.m in Headers */, 205F0E1D1B373A2C007741D0 /* ASCollectionViewLayoutController.h in Headers */, + ACF6ED4E1B17847A00DA7C62 /* ASStackLayoutNodeUtilities.h in Headers */, 058D0A6F195D05EC00B7D73C /* UIView+ASConvenience.h in Headers */, 058D0A70195D05EC00B7D73C /* UIView+ASConvenience.m in Headers */, + ACF6ED2A1B17843500DA7C62 /* ASLayoutNodeSubclass.h in Headers */, 058D0A82195D060300B7D73C /* ASAssert.h in Headers */, 0516FA3C1A15563400B4EBED /* ASAvailability.h in Headers */, 0516FA3D1A15563400B4EBED /* ASLog.h in Headers */, 058D0A83195D060300B7D73C /* ASBaseDefines.h in Headers */, 058D0A84195D060300B7D73C /* ASDisplayNodeExtraIvars.h in Headers */, AC3C4A511A1139C100143C57 /* ASCollectionView.h in Headers */, + ACF6ED4D1B17847A00DA7C62 /* ASLayoutNodeUtilities.h in Headers */, 292C59A01A956527007E5DD6 /* ASRangeHandlerPreload.h in Headers */, 055B9FA81A1C154B00035D6D /* ASNetworkImageNode.h in Headers */, + ACF6ED4F1B17847A00DA7C62 /* ASStackPositionedLayout.h in Headers */, 054963491A1EA066000F8E56 /* ASBasicImageDownloader.h in Headers */, AC3C4A541A113EEC00143C57 /* ASCollectionViewProtocols.h in Headers */, D785F6621A74327E00291744 /* ASScrollNode.h in Headers */, 0587F9BD1A7309ED00AFF0BA /* ASEditableTextNode.h in Headers */, + ACF6ED311B17843500DA7C62 /* ASStaticLayoutNode.h in Headers */, 05F20AA41A15733C00DCA68A /* ASImageProtocols.h in Headers */, 058D0A71195D05F800B7D73C /* _AS-objc-internal.h in Headers */, 058D0A72195D05F800B7D73C /* _ASCoreAnimationExtras.h in Headers */, @@ -913,6 +1035,7 @@ 058D0A74195D05F800B7D73C /* _ASPendingState.h in Headers */, 058D0A75195D05F800B7D73C /* _ASPendingState.m in Headers */, 058D0A76195D05F900B7D73C /* _ASScopeTimer.h in Headers */, + ACF6ED241B17843500DA7C62 /* ASLayout.h in Headers */, 058D0A77195D05F900B7D73C /* ASDisplayNode+AsyncDisplay.mm in Headers */, 058D0A78195D05F900B7D73C /* ASDisplayNode+DebugTiming.h in Headers */, 058D0A79195D05F900B7D73C /* ASDisplayNode+DebugTiming.mm in Headers */, @@ -925,7 +1048,9 @@ 292C59A21A956527007E5DD6 /* ASRangeHandler.h in Headers */, 058D0A7F195D05F900B7D73C /* ASSentinel.h in Headers */, 058D0A80195D05F900B7D73C /* ASSentinel.m in Headers */, + ACF6ED1E1B17843500DA7C62 /* ASCompositeNode.h in Headers */, 058D0A81195D05F900B7D73C /* ASThread.h in Headers */, + ACF6ED2F1B17843500DA7C62 /* ASStackLayoutNode.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1199,18 +1324,27 @@ 058D0A26195D050800B7D73C /* _ASCoreAnimationExtras.mm in Sources */, 058D0A23195D050800B7D73C /* _ASAsyncTransactionContainer.m in Sources */, 058D0A1E195D050800B7D73C /* ASTextNodeShadower.m in Sources */, + ACF6ED2E1B17843500DA7C62 /* ASRatioLayoutNode.mm in Sources */, 058D0A18195D050800B7D73C /* _ASDisplayLayer.mm in Sources */, + ACF6ED321B17843500DA7C62 /* ASStaticLayoutNode.mm in Sources */, + ACF6ED2C1B17843500DA7C62 /* ASOverlayLayoutNode.mm in Sources */, 058D0A2C195D050800B7D73C /* ASSentinel.m in Sources */, 205F0E221B376416007741D0 /* CGRect+ASConvenience.m in Sources */, 205F0E1A1B37339C007741D0 /* ASAbstractLayoutController.mm in Sources */, 464052211A3F83C40061C0BA /* ASDataController.mm in Sources */, 299DA1AA1A828D2900162D41 /* ASBatchContext.mm in Sources */, 058D0A15195D050800B7D73C /* ASDisplayNodeExtras.mm in Sources */, + ACF6ED501B17847A00DA7C62 /* ASStackPositionedLayout.mm in Sources */, 058D0A1F195D050800B7D73C /* ASTextNodeTextKitHelpers.mm in Sources */, + ACF6ED1B1B17843500DA7C62 /* ASBackgroundLayoutNode.mm in Sources */, 055F1A3519ABD3E3004DAFF1 /* ASTableView.mm in Sources */, 205F0E121B371BD7007741D0 /* ASScrollDirection.m in Sources */, + ACF6ED271B17843500DA7C62 /* ASLayoutNode.mm in Sources */, + ACF6ED211B17843500DA7C62 /* ASDimension.mm in Sources */, 464052261A3F83C40061C0BA /* ASMultidimensionalArrayUtils.mm in Sources */, 055B9FA91A1C154B00035D6D /* ASNetworkImageNode.mm in Sources */, + ACF6ED521B17847A00DA7C62 /* ASStackUnpositionedLayout.mm in Sources */, + ACF6ED1D1B17843500DA7C62 /* ASCenterLayoutNode.mm in Sources */, 058D0A1D195D050800B7D73C /* ASTextNodeRenderer.mm in Sources */, 292C59A41A956527007E5DD6 /* ASRangeHandlerRender.mm in Sources */, 058D0A2A195D050800B7D73C /* ASDisplayNode+UIViewBridge.mm in Sources */, @@ -1218,29 +1352,35 @@ 292C59A11A956527007E5DD6 /* ASRangeHandlerPreload.mm in Sources */, 058D0A20195D050800B7D73C /* ASTextNodeWordKerner.m in Sources */, 058D0A1A195D050800B7D73C /* ASHighlightOverlayLayer.mm in Sources */, + ACF6ED291B17843500DA7C62 /* ASLayoutNodeSize.mm in Sources */, 464052231A3F83C40061C0BA /* ASFlowLayoutController.mm in Sources */, 058D0A28195D050800B7D73C /* ASDisplayNode+AsyncDisplay.mm in Sources */, 0587F9BE1A7309ED00AFF0BA /* ASEditableTextNode.mm in Sources */, 058D0A21195D050800B7D73C /* NSMutableAttributedString+TextKitAdditions.m in Sources */, + ACF6ED251B17843500DA7C62 /* ASLayout.mm in Sources */, 058D0A25195D050800B7D73C /* UIView+ASConvenience.m in Sources */, 0549634A1A1EA066000F8E56 /* ASBasicImageDownloader.mm in Sources */, 058D0A14195D050800B7D73C /* ASDisplayNode.mm in Sources */, 058D0A1B195D050800B7D73C /* ASMutableAttributedStringBuilder.m in Sources */, 058D0A2B195D050800B7D73C /* ASImageNode+CGExtras.m in Sources */, 058D0A24195D050800B7D73C /* _ASAsyncTransactionGroup.m in Sources */, - 055F1A3D19ABD43F004DAFF1 /* ASCellNode.m in Sources */, 058D0A1C195D050800B7D73C /* ASTextNodeCoreTextAdditions.m in Sources */, 058D0A13195D050800B7D73C /* ASControlNode.m in Sources */, + ACF6ED4C1B17847A00DA7C62 /* ASInternalHelpers.mm in Sources */, + ACF6ED1F1B17843500DA7C62 /* ASCompositeNode.mm in Sources */, 058D0A19195D050800B7D73C /* _ASDisplayView.mm in Sources */, 205F0E101B371875007741D0 /* UICollectionViewLayout+ASConvenience.m in Sources */, 05A6D05B19D0EB64002DD95E /* ASDealloc2MainObject.m in Sources */, 058D0A17195D050800B7D73C /* ASTextNode.mm in Sources */, + AC6456091B0A335000CF11B8 /* ASCellNode.mm in Sources */, + ACF6ED231B17843500DA7C62 /* ASInsetLayoutNode.mm in Sources */, 058D0A27195D050800B7D73C /* _ASPendingState.m in Sources */, 0516FA411A1563D200B4EBED /* ASMultiplexImageNode.mm in Sources */, 058D0A16195D050800B7D73C /* ASImageNode.mm in Sources */, 058D0A29195D050800B7D73C /* ASDisplayNode+DebugTiming.mm in Sources */, 205F0E1E1B373A2C007741D0 /* ASCollectionViewLayoutController.mm in Sources */, 058D0A22195D050800B7D73C /* _ASAsyncTransaction.m in Sources */, + ACF6ED301B17843500DA7C62 /* ASStackLayoutNode.mm in Sources */, 055F1A3919ABD413004DAFF1 /* ASRangeController.mm in Sources */, 296A0A2F1A9516B2005ACEAA /* ASBatchFetching.m in Sources */, D785F6631A74327E00291744 /* ASScrollNode.m in Sources */, @@ -1298,7 +1438,7 @@ B350621E1B010EFD0018CF92 /* ASHighlightOverlayLayer.mm in Sources */, B35062271B010EFD0018CF92 /* ASRangeController.mm in Sources */, B35061F91B010EFD0018CF92 /* ASControlNode.m in Sources */, - B35061F41B010EFD0018CF92 /* ASCellNode.m in Sources */, + AC6456091B0A335000CF11B8 /* ASCellNode.mm in Sources */, 509E68661B3AEDD7009B9150 /* CGRect+ASConvenience.m in Sources */, B35062561B010EFD0018CF92 /* ASSentinel.m in Sources */, B350624A1B010EFD0018CF92 /* _ASCoreAnimationExtras.mm in Sources */, diff --git a/AsyncDisplayKit/ASCellNode.m b/AsyncDisplayKit/ASCellNode.mm similarity index 80% rename from AsyncDisplayKit/ASCellNode.m rename to AsyncDisplayKit/ASCellNode.mm index c9a6955c6d..245b261c48 100644 --- a/AsyncDisplayKit/ASCellNode.m +++ b/AsyncDisplayKit/ASCellNode.mm @@ -12,6 +12,8 @@ #import #import +#import "ASInsetLayoutNode.h" +#import "ASCompositeNode.h" #pragma mark - #pragma mark ASCellNode @@ -91,8 +93,6 @@ @implementation ASTextCellNode -static const CGFloat kHorizontalPadding = 15.0f; -static const CGFloat kVerticalPadding = 11.0f; static const CGFloat kFontSize = 18.0f; - (instancetype)init @@ -106,21 +106,12 @@ static const CGFloat kFontSize = 18.0f; return self; } -- (CGSize)calculateSizeThatFits:(CGSize)constrainedSize +- (ASLayoutNode *)layoutNodeThatFits:(CGSize)constrainedSize { - CGSize availableSize = CGSizeMake(constrainedSize.width - 2 * kHorizontalPadding, - constrainedSize.height - 2 * kVerticalPadding); - availableSize.width = MAX(0, availableSize.width); - availableSize.height = MAX(0, availableSize.height); - CGSize textNodeSize = [_textNode measure:availableSize]; - - return CGSizeMake(ceilf(2 * kHorizontalPadding + textNodeSize.width), - ceilf(2 * kVerticalPadding + textNodeSize.height)); -} - -- (void)layout -{ - _textNode.frame = CGRectInset(self.bounds, kHorizontalPadding, kVerticalPadding); + static const CGFloat kHorizontalPadding = 15.0f; + static const CGFloat kVerticalPadding = 11.0f; + UIEdgeInsets insets = UIEdgeInsetsMake(kVerticalPadding, kHorizontalPadding, kVerticalPadding, kHorizontalPadding); + return [ASInsetLayoutNode newWithInsets:insets node:[ASCompositeNode newWithDisplayNode:_textNode]]; } - (void)setText:(NSString *)text @@ -132,7 +123,7 @@ static const CGFloat kFontSize = 18.0f; _textNode.attributedString = [[NSAttributedString alloc] initWithString:_text attributes:@{NSFontAttributeName: [UIFont systemFontOfSize:kFontSize]}]; - [self invalidateCalculatedSize]; + [self invalidateCalculatedLayout]; } @end diff --git a/AsyncDisplayKit/ASDisplayNode+Subclasses.h b/AsyncDisplayKit/ASDisplayNode+Subclasses.h index 106cc375cc..8f4be8e030 100644 --- a/AsyncDisplayKit/ASDisplayNode+Subclasses.h +++ b/AsyncDisplayKit/ASDisplayNode+Subclasses.h @@ -13,6 +13,8 @@ #import #import +#import +@class ASLayoutNode; /** * The subclass header _ASDisplayNode+Subclasses_ defines the following methods that either must or can be overriden by @@ -65,6 +67,17 @@ */ @property (nonatomic, readonly, assign, getter=isInHierarchy) BOOL inHierarchy; +/** + * @abstract Return the calculated layout. + * + * @discussion Ideal for use by subclasses in -layout, having already prompted their subnodes to calculate their size by + * calling -measure: on them in -calculateLayoutThatFits:. + * + * @return Layout already calculated by ASLayoutNode returned by layoutNodeThatFits:. + * + * @warning Subclasses must not override this; it returns the last cached layout and is never expensive. + */ +@property (nonatomic, readonly, assign) ASLayout *calculatedLayout; /** @name View Lifecycle */ @@ -95,31 +108,29 @@ */ - (void)layoutDidFinish; - -/** @name Sizing */ - +- (ASLayoutNode *)layoutNodeThatFits:(CGSize)constrainedSize; /** - * @abstract Return the calculated size. + * @abstract Return the calculated layout. * * @param constrainedSize The maximum size the receiver should fit in. * - * @discussion Subclasses that override should expect this method to be called on a non-main thread. The returned size + * @discussion Subclasses that override should expect this method to be called on a non-main thread. The returned layout * is cached by ASDisplayNode for quick access during -layout, via -calculatedSize. Other expensive work that needs to * be done before display can be performed here, and using ivars to cache any valuable intermediate results is * encouraged. * - * @note This method should not be called directly outside of ASDisplayNode; use -measure: or -calculatedSize instead. + * @note This method should not be called directly outside of ASDisplayNode; use -measure: or -calculatedLayout instead. */ -- (CGSize)calculateSizeThatFits:(CGSize)constrainedSize; +- (ASLayout *)calculateLayoutThatFits:(CGSize)constrainedSize; /** - * @abstract Invalidate previously measured and cached size. + * @abstract Invalidate previously measured and cached layout. * - * @discussion Subclasses should call this method to invalidate the previously measured and cached size for the display + * @discussion Subclasses should call this method to invalidate the previously measured and cached layout for the display * node, when the contents of the node change in such a way as to require measuring it again. */ -- (void)invalidateCalculatedSize; +- (void)invalidateCalculatedLayout; /** @name Drawing */ diff --git a/AsyncDisplayKit/ASDisplayNode.h b/AsyncDisplayKit/ASDisplayNode.h index c963439c65..78479903a0 100644 --- a/AsyncDisplayKit/ASDisplayNode.h +++ b/AsyncDisplayKit/ASDisplayNode.h @@ -128,10 +128,10 @@ typedef CALayer *(^ASDisplayNodeLayerBlock)(); * @discussion Though this method does not set the bounds of the view, it does have side effects--caching both the * constraint and the result. * - * @warning Subclasses must not override this; it caches results from -calculateSizeThatFits:. Calling this method may + * @warning Subclasses must not override this; it caches results from -layoutNodeThatFits:. Calling this method may * be expensive if result is not cached. * - * @see [ASDisplayNode(Subclassing) calculateSizeThatFits:] + * @see [ASDisplayNode(Subclassing) layoutNodeThatFits:] */ - (CGSize)measure:(CGSize)constrainedSize; @@ -139,20 +139,20 @@ typedef CALayer *(^ASDisplayNodeLayerBlock)(); * @abstract Return the calculated size. * * @discussion Ideal for use by subclasses in -layout, having already prompted their subnodes to calculate their size by - * calling -measure: on them in -calculateSizeThatFits:. + * calling -measure: on them in -calculateLayoutThatFits. * - * @return Size already calculated by calculateSizeThatFits:. + * @return Size already calculated by -calculateLayoutThatFits:. * - * @warning Subclasses must not override this; it returns the last cached size calculated and is never expensive. + * @warning Subclasses must not override this; it returns the last cached measurement and is never expensive. */ @property (nonatomic, readonly, assign) CGSize calculatedSize; /** - * @abstract Return the constrained size used for calculating size. + * @abstract Return the constrained size used for calculating layout. * - * @return The constrained size used by calculateSizeThatFits:. + * @return The constrained size used by layoutNodeThatFits:. */ -@property (nonatomic, readonly, assign) CGSize constrainedSizeForCalculatedSize; +@property (nonatomic, readonly, assign) CGSize constrainedSizeForCalculatedLayout; /** @name Managing the nodes hierarchy */ diff --git a/AsyncDisplayKit/ASDisplayNode.mm b/AsyncDisplayKit/ASDisplayNode.mm index c1a269e559..0c4ff8466b 100644 --- a/AsyncDisplayKit/ASDisplayNode.mm +++ b/AsyncDisplayKit/ASDisplayNode.mm @@ -11,6 +11,7 @@ #import "ASDisplayNodeInternal.h" #import +#import #import "_ASAsyncTransaction.h" #import "_ASPendingState.h" @@ -18,6 +19,11 @@ #import "_ASScopeTimer.h" #import "ASDisplayNodeExtras.h" +#import "ASInternalHelpers.h" +#import "ASLayoutNodeSubclass.h" +#import "ASCompositeNode.h" +#import "ASLayoutNodeUtilities.h" + @interface ASDisplayNode () /** @@ -37,39 +43,6 @@ @implementation ASDisplayNode -BOOL ASDisplayNodeSubclassOverridesSelector(Class subclass, SEL selector) -{ - Method superclassMethod = class_getInstanceMethod([ASDisplayNode class], selector); - Method subclassMethod = class_getInstanceMethod(subclass, selector); - IMP superclassIMP = superclassMethod ? method_getImplementation(superclassMethod) : NULL; - IMP subclassIMP = subclassMethod ? method_getImplementation(subclassMethod) : NULL; - - return (superclassIMP != subclassIMP); -} - -CGFloat ASDisplayNodeScreenScale() -{ - static CGFloat screenScale = 0.0; - static dispatch_once_t onceToken; - ASDispatchOnceOnMainThread(&onceToken, ^{ - screenScale = [[UIScreen mainScreen] scale]; - }); - return screenScale; -} - -static void ASDispatchOnceOnMainThread(dispatch_once_t *predicate, dispatch_block_t block) -{ - if ([NSThread isMainThread]) { - dispatch_once(predicate, block); - } else { - if (DISPATCH_EXPECT(*predicate == 0L, NO)) { - dispatch_sync(dispatch_get_main_queue(), ^{ - dispatch_once(predicate, block); - }); - } - } -} - void ASDisplayNodePerformBlockOnMainThread(void (^block)()) { if ([NSThread isMainThread]) { @@ -88,10 +61,11 @@ void ASDisplayNodePerformBlockOnMainThread(void (^block)()) } // Subclasses should never override these - ASDisplayNodeAssert(!ASDisplayNodeSubclassOverridesSelector(self, @selector(calculatedSize)), @"Subclass %@ must not override calculatedSize method", NSStringFromClass(self)); - ASDisplayNodeAssert(!ASDisplayNodeSubclassOverridesSelector(self, @selector(measure:)), @"Subclass %@ must not override measure method", NSStringFromClass(self)); - ASDisplayNodeAssert(!ASDisplayNodeSubclassOverridesSelector(self, @selector(recursivelyClearContents)), @"Subclass %@ must not override recursivelyClearContents method", NSStringFromClass(self)); - ASDisplayNodeAssert(!ASDisplayNodeSubclassOverridesSelector(self, @selector(recursivelyClearFetchedData)), @"Subclass %@ must not override recursivelyClearFetchedData method", NSStringFromClass(self)); + ASDisplayNodeAssert(!ASSubclassOverridesSelector([ASDisplayNode class], self, @selector(calculatedSize)), @"Subclass %@ must not override calculatedSize method", NSStringFromClass(self)); + ASDisplayNodeAssert(!ASSubclassOverridesSelector([ASDisplayNode class], self, @selector(calculatedLayout)), @"Subclass %@ must not override calculatedLayout method", NSStringFromClass(self)); + ASDisplayNodeAssert(!ASSubclassOverridesSelector([ASDisplayNode class], self, @selector(measure:)), @"Subclass %@ must not override measure method", NSStringFromClass(self)); + ASDisplayNodeAssert(!ASSubclassOverridesSelector([ASDisplayNode class], self, @selector(recursivelyClearContents)), @"Subclass %@ must not override recursivelyClearContents method", NSStringFromClass(self)); + ASDisplayNodeAssert(!ASSubclassOverridesSelector([ASDisplayNode class], self, @selector(recursivelyClearFetchedData)), @"Subclass %@ must not override recursivelyClearFetchedData method", NSStringFromClass(self)); } + (BOOL)layerBackedNodesEnabled @@ -113,7 +87,7 @@ void ASDisplayNodePerformBlockOnMainThread(void (^block)()) - (void)_initializeInstance { - _contentsScaleForDisplay = ASDisplayNodeScreenScale(); + _contentsScaleForDisplay = ASScreenScale(); _displaySentinel = [[ASSentinel alloc] init]; @@ -126,16 +100,16 @@ void ASDisplayNodePerformBlockOnMainThread(void (^block)()) _flags.implementsDrawParameters = ([self respondsToSelector:@selector(drawParametersForAsyncLayer:)] ? 1 : 0); ASDisplayNodeMethodOverrides overrides = ASDisplayNodeMethodOverrideNone; - if (ASDisplayNodeSubclassOverridesSelector([self class], @selector(touchesBegan:withEvent:))) { + if (ASSubclassOverridesSelector([ASDisplayNode class], [self class], @selector(touchesBegan:withEvent:))) { overrides |= ASDisplayNodeMethodOverrideTouchesBegan; } - if (ASDisplayNodeSubclassOverridesSelector([self class], @selector(touchesMoved:withEvent:))) { + if (ASSubclassOverridesSelector([ASDisplayNode class], [self class], @selector(touchesMoved:withEvent:))) { overrides |= ASDisplayNodeMethodOverrideTouchesMoved; } - if (ASDisplayNodeSubclassOverridesSelector([self class], @selector(touchesCancelled:withEvent:))) { + if (ASSubclassOverridesSelector([ASDisplayNode class], [self class], @selector(touchesCancelled:withEvent:))) { overrides |= ASDisplayNodeMethodOverrideTouchesCancelled; } - if (ASDisplayNodeSubclassOverridesSelector([self class], @selector(touchesEnded:withEvent:))) { + if (ASSubclassOverridesSelector([ASDisplayNode class], [self class], @selector(touchesEnded:withEvent:))) { overrides |= ASDisplayNodeMethodOverrideTouchesEnded; } _methodOverrides = overrides; @@ -453,17 +427,17 @@ void ASDisplayNodePerformBlockOnMainThread(void (^block)()) // - the width is different from the last time // - the height is different from the last time if (!_flags.isMeasured || !CGSizeEqualToSize(constrainedSize, _constrainedSize)) { - _size = [self calculateSizeThatFits:constrainedSize]; + _layout = [self calculateLayoutThatFits:constrainedSize]; _constrainedSize = constrainedSize; _flags.isMeasured = YES; } - ASDisplayNodeAssertTrue(_size.width >= 0.0); - ASDisplayNodeAssertTrue(_size.height >= 0.0); + ASDisplayNodeAssertTrue(_layout.size.width >= 0.0); + ASDisplayNodeAssertTrue(_layout.size.height >= 0.0); // we generate placeholders at measure: time so that a node is guaranteed to have a placeholder ready to go // also if a node has no size, it should not have a placeholder - if (self.placeholderEnabled && [self _displaysAsynchronously] && _size.width > 0.0 && _size.height > 0.0) { + if (self.placeholderEnabled && [self _displaysAsynchronously] && _layout.size.width > 0.0 && _layout.size.height > 0.0) { if (!_placeholderImage) { _placeholderImage = [self placeholderImage]; } @@ -473,7 +447,7 @@ void ASDisplayNodePerformBlockOnMainThread(void (^block)()) } } - return _size; + return _layout.size; } - (BOOL)displaysAsynchronously @@ -1282,16 +1256,30 @@ static NSInteger incrementIfFound(NSInteger i) { #pragma mark - For Subclasses -- (CGSize)calculateSizeThatFits:(CGSize)constrainedSize +- (ASLayoutNode *)layoutNodeThatFits:(CGSize)constrainedSize { ASDisplayNodeAssertThreadAffinity(self); - return CGSizeZero; + return [ASLayoutNode new]; +} + +- (ASLayout *)calculateLayoutThatFits:(CGSize)constrainedSize +{ + ASDisplayNodeAssertThreadAffinity(self); + ASLayoutNode *layoutNode = [self layoutNodeThatFits:constrainedSize]; + ASLayout *layout = [layoutNode layoutThatFits:{CGSizeZero, constrainedSize} parentSize:constrainedSize]; + return layout; +} + +- (ASLayout *)calculatedLayout +{ + ASDisplayNodeAssertThreadAffinity(self); + return _layout; } - (CGSize)calculatedSize { ASDisplayNodeAssertThreadAffinity(self); - return _size; + return _layout.size; } - (CGSize)constrainedSizeForCalculatedSize @@ -1305,7 +1293,7 @@ static NSInteger incrementIfFound(NSInteger i) { return nil; } -- (void)invalidateCalculatedSize +- (void)invalidateCalculatedLayout { ASDisplayNodeAssertThreadAffinity(self); // This will cause -measure: to actually compute the size instead of returning the previously cached size @@ -1376,6 +1364,43 @@ static NSInteger incrementIfFound(NSInteger i) { - (void)layout { ASDisplayNodeAssertMainThread(); + + if (!_flags.isMeasured) { + return; + } + + struct Context { + ASLayout *layout; + CGPoint absoultePosition; + BOOL visited; + }; + + // Stack of Contexts, used to keep track of layout nodes while traversing the calculated layout in a DFS fashion. + std::stack stack; + stack.push({_layout, CGPointMake(0, 0), NO}); + + while (!stack.empty()) { + Context &context = stack.top(); + if (context.visited) { + stack.pop(); + } else { + ASDisplayNodeAssertNotNil(context.layout.node, "node is required in calculated ASLayout."); + context.visited = YES; + + if ([context.layout.node isKindOfClass:[ASCompositeNode class]]) { + ASDisplayNode *subnode = ((ASCompositeNode *)context.layout.node).displayNode; + ASDisplayNodeAssertNotNil(subnode, "displayNode is required in ASCompositeNode."); + + CGPoint subnodePosition = context.absoultePosition; + CGSize subnodeSize = context.layout.size; + subnode.frame = CGRectMake(subnodePosition.x, subnodePosition.y, subnodeSize.width, subnodeSize.height); + } + + for (ASLayoutChild *child in context.layout.children) { + stack.push({child.layout, context.absoultePosition + child.position, NO}); + } + } + } } - (void)displayWillStart diff --git a/AsyncDisplayKit/ASEditableTextNode.mm b/AsyncDisplayKit/ASEditableTextNode.mm index 0b757d1752..295d09e4b2 100644 --- a/AsyncDisplayKit/ASEditableTextNode.mm +++ b/AsyncDisplayKit/ASEditableTextNode.mm @@ -16,6 +16,8 @@ #import "ASTextNodeWordKerner.h" #import "ASThread.h" +#import "ASLayoutNode.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 @end @@ -143,16 +145,17 @@ [self.view addSubview:_textKitComponents.textView]; } -- (CGSize)calculateSizeThatFits:(CGSize)constrainedSize +- (ASLayout *)calculateLayoutThatFits:(CGSize)constrainedSize { ASTextKitComponents *displayedComponents = [self isDisplayingPlaceholder] ? _placeholderTextKitComponents : _textKitComponents; CGSize textSize = [displayedComponents sizeForConstrainedWidth:constrainedSize.width]; - return CGSizeMake(constrainedSize.width, fminf(textSize.height, constrainedSize.height)); + CGSize finalSize = CGSizeMake(constrainedSize.width, fminf(textSize.height, constrainedSize.height)); + return [ASLayout newWithNode:[ASLayoutNode new] size:finalSize]; } - (void)layout { - [super layout]; + ASDisplayNodeAssertMainThread(); [self _layoutTextView]; } @@ -290,7 +293,7 @@ [_textKitComponents.textStorage setAttributedString:attributedStringToDisplay]; // Calculated size depends on the seeded text. - [self invalidateCalculatedSize]; + [self invalidateCalculatedLayout]; // Update if placeholder is shown. [self _updateDisplayingPlaceholder]; @@ -389,7 +392,7 @@ [self _updateDisplayingPlaceholder]; // Invalidate, as our calculated size depends on the textview's seeded text. - [self invalidateCalculatedSize]; + [self invalidateCalculatedLayout]; // Delegateify. [self _delegateDidUpdateText]; diff --git a/AsyncDisplayKit/ASImageNode.mm b/AsyncDisplayKit/ASImageNode.mm index 2d61599626..aaff46526f 100644 --- a/AsyncDisplayKit/ASImageNode.mm +++ b/AsyncDisplayKit/ASImageNode.mm @@ -17,6 +17,9 @@ #import "ASImageNode+CGExtras.h" +#import "ASInternalHelpers.h" +#import "ASLayoutNode.h" + @interface _ASImageNodeDrawParameters : NSObject @property (nonatomic, assign, readonly) BOOL cropEnabled; @@ -82,7 +85,7 @@ return nil; // TODO can this be removed? - self.contentsScale = ASDisplayNodeScreenScale(); + self.contentsScale = ASScreenScale(); self.contentMode = UIViewContentModeScaleAspectFill; self.opaque = NO; @@ -106,13 +109,13 @@ return nil; } -- (CGSize)calculateSizeThatFits:(CGSize)constrainedSize +- (ASLayout *)calculateLayoutThatFits:(CGSize)constrainedSize { ASDN::MutexLocker l(_imageLock); + CGSize size = CGSizeZero; if (_image) - return _image.size; - else - return CGSizeZero; + size = _image.size; + return [ASLayout newWithNode:[ASLayoutNode new] size:size]; } - (void)setImage:(UIImage *)image @@ -123,7 +126,7 @@ ASDN::MutexUnlocker u(_imageLock); ASDisplayNodePerformBlockOnMainThread(^{ - [self invalidateCalculatedSize]; + [self invalidateCalculatedLayout]; [self setNeedsDisplay]; }); } diff --git a/AsyncDisplayKit/ASTextNode.mm b/AsyncDisplayKit/ASTextNode.mm index a170709724..4f7b6c64b5 100644 --- a/AsyncDisplayKit/ASTextNode.mm +++ b/AsyncDisplayKit/ASTextNode.mm @@ -19,6 +19,8 @@ #import "ASTextNodeRenderer.h" #import "ASTextNodeShadower.h" +#import "ASLayoutNode.h" + static const NSTimeInterval ASTextNodeHighlightFadeOutDuration = 0.15; static const NSTimeInterval ASTextNodeHighlightFadeInDuration = 0.1; static const CGFloat ASTextNodeHighlightLightOpacity = 0.11; @@ -184,7 +186,7 @@ ASDISPLAYNODE_INLINE CGFloat ceilPixelValue(CGFloat f) #pragma mark - ASDisplayNode -- (CGSize)calculateSizeThatFits:(CGSize)constrainedSize +- (ASLayout *)calculateLayoutThatFits:(CGSize)constrainedSize { ASDisplayNodeAssert(constrainedSize.width >= 0, @"Constrained width for text (%f) is too narrow", constrainedSize.width); ASDisplayNodeAssert(constrainedSize.height >= 0, @"Constrained height for text (%f) is too short", constrainedSize.height); @@ -210,8 +212,9 @@ ASDISPLAYNODE_INLINE CGFloat ceilPixelValue(CGFloat f) ASDisplayNodeAssert(renderSizePlusShadowPadding.width >= 0, @"Calculated width for text with shadow padding (%f) is too narrow", constrainedSizeForText.width); ASDisplayNodeAssert(renderSizePlusShadowPadding.height >= 0, @"Calculated height for text with shadow padding (%f) is too short", constrainedSizeForText.height); - return CGSizeMake(MIN(ceilPixelValue(renderSizePlusShadowPadding.width), constrainedSize.width), - MIN(ceilPixelValue(renderSizePlusShadowPadding.height), constrainedSize.height)); + CGSize finalSize = CGSizeMake(MIN(ceilPixelValue(renderSizePlusShadowPadding.width), constrainedSize.width), + MIN(ceilPixelValue(renderSizePlusShadowPadding.height), constrainedSize.height)); + return [ASLayout newWithNode:[ASLayoutNode new] size:finalSize]; } - (void)displayDidFinish @@ -337,8 +340,8 @@ ASDISPLAYNODE_INLINE CGFloat ceilPixelValue(CGFloat f) // We need an entirely new renderer [self _invalidateRenderer]; - // Tell the display node superclasses that the cached sizes are incorrect now - [self invalidateCalculatedSize]; + // Tell the display node superclasses that the cached layout is incorrect now + [self invalidateCalculatedLayout]; [self setNeedsDisplay]; @@ -359,7 +362,7 @@ ASDISPLAYNODE_INLINE CGFloat ceilPixelValue(CGFloat f) if ((_exclusionPaths == nil && exclusionPaths != nil) || (![_exclusionPaths isEqualToArray:exclusionPaths])) { _exclusionPaths = exclusionPaths; [self _invalidateRenderer]; - [self invalidateCalculatedSize]; + [self invalidateCalculatedLayout]; [self setNeedsDisplay]; } } diff --git a/AsyncDisplayKit/AsyncDisplayKit.h b/AsyncDisplayKit/AsyncDisplayKit.h index 2fe59c2a16..c2638a8ef3 100644 --- a/AsyncDisplayKit/AsyncDisplayKit.h +++ b/AsyncDisplayKit/AsyncDisplayKit.h @@ -24,3 +24,16 @@ #import #import + +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import diff --git a/AsyncDisplayKit/Details/ASHighlightOverlayLayer.mm b/AsyncDisplayKit/Details/ASHighlightOverlayLayer.mm index efdf7c6eb6..acaa97f00e 100644 --- a/AsyncDisplayKit/Details/ASHighlightOverlayLayer.mm +++ b/AsyncDisplayKit/Details/ASHighlightOverlayLayer.mm @@ -10,7 +10,7 @@ #import -#import +#import "ASInternalHelpers.h" static const CGFloat kCornerRadius = 2.5; static const UIEdgeInsets padding = {2, 4, 1.5, 4}; @@ -23,7 +23,7 @@ static const UIEdgeInsets padding = {2, 4, 1.5, 4}; + (id)defaultValueForKey:(NSString *)key { if ([key isEqualToString:@"contentsScale"]) { - return @(ASDisplayNodeScreenScale()); + return @(ASScreenScale()); } else if ([key isEqualToString:@"highlightColor"]) { CGFloat components[] = {0, 0, 0, 0.25}; CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); diff --git a/AsyncDisplayKit/Private/ASDisplayNodeInternal.h b/AsyncDisplayKit/Private/ASDisplayNodeInternal.h index 4988d60211..8723dbb9f5 100644 --- a/AsyncDisplayKit/Private/ASDisplayNodeInternal.h +++ b/AsyncDisplayKit/Private/ASDisplayNodeInternal.h @@ -17,9 +17,8 @@ #import "ASDisplayNode.h" #import "ASSentinel.h" #import "ASThread.h" +#import "ASLayout.h" -BOOL ASDisplayNodeSubclassOverridesSelector(Class subclass, SEL selector); -CGFloat ASDisplayNodeScreenScale(); void ASDisplayNodePerformBlockOnMainThread(void (^block)()); typedef NS_OPTIONS(NSUInteger, ASDisplayNodeMethodOverrides) { @@ -51,7 +50,7 @@ typedef NS_OPTIONS(NSUInteger, ASDisplayNodeMethodOverrides) { // This is the desired contentsScale, not the scale at which the layer's contents should be displayed CGFloat _contentsScaleForDisplay; - CGSize _size; + ASLayout *_layout; CGSize _constrainedSize; UIEdgeInsets _hitTestSlop; NSMutableArray *_subnodes; diff --git a/Base/ASAssert.h b/Base/ASAssert.h index 84fed6977f..589e954558 100644 --- a/Base/ASAssert.h +++ b/Base/ASAssert.h @@ -47,3 +47,10 @@ #define ASDisplayNodeFailAssert(description, ...) ASDisplayNodeAssertWithSignal(NO, nil, (description), ##__VA_ARGS__) #define ASDisplayNodeCFailAssert(description, ...) ASDisplayNodeCAssertWithSignal(NO, nil, (description), ##__VA_ARGS__) + +#define ASDisplayNodeConditionalAssert(shouldTestCondition, condition, description, ...) ASDisplayNodeAssert((!(shouldTestCondition) || (condition)), nil, (description), ##__VA_ARGS__) +#define ASDisplayNodeConditionalCAssert(shouldTestCondition, condition, description, ...) ASDisplayNodeCAssert((!(shouldTestCondition) || (condition)), nil, (description), ##__VA_ARGS__) + +#define ASDisplayNodeCAssertPositiveReal(description, num) ASDisplayNodeCAssert(num >= 0 && num < CGFLOAT_MAX, @"%@ must be a real positive integer.", description) +#define ASDisplayNodeCAssertInfOrPositiveReal(description, num) ASDisplayNodeCAssert(isinf(num) || (num >= 0 && num < CGFLOAT_MAX), @"%@ must be infinite or a real positive integer.", description) +