[Layout] Move [ASLayoutSpec children] from std::map to NSMutableArray (#2253)

* Initial commit to move [ASLayoutSpec children] from std::map to NSMutableArray

* Add NSFastEnumeration to ASLayoutable

* ASNullLayoutSpec is a Singleton now

* Move ASLayoutSpecPrivate in Private folder

* Move to NSArrayPointer and remove ASNullLayoutSpec

* Revert "Move to NSArrayPointer and remove ASNullLayoutSpec"

This reverts commit 9ab9cf7024b1f6e1984d84fe58af2b84e84cdf94.

* Move to childAtIndex: and setChild:atIndex:
This commit is contained in:
Michael Schneider
2016-09-27 16:41:45 -07:00
committed by Adlai Holler
parent 8a4d4e3b5c
commit 2f99951732
13 changed files with 341 additions and 154 deletions

View File

@@ -206,6 +206,9 @@
69708BA61D76386D005C3CF9 /* ASEqualityHashHelpers.h in Headers */ = {isa = PBXBuildFile; fileRef = 69708BA41D76386D005C3CF9 /* ASEqualityHashHelpers.h */; }; 69708BA61D76386D005C3CF9 /* ASEqualityHashHelpers.h in Headers */ = {isa = PBXBuildFile; fileRef = 69708BA41D76386D005C3CF9 /* ASEqualityHashHelpers.h */; };
69708BA71D76386D005C3CF9 /* ASEqualityHashHelpers.mm in Sources */ = {isa = PBXBuildFile; fileRef = 69708BA51D76386D005C3CF9 /* ASEqualityHashHelpers.mm */; }; 69708BA71D76386D005C3CF9 /* ASEqualityHashHelpers.mm in Sources */ = {isa = PBXBuildFile; fileRef = 69708BA51D76386D005C3CF9 /* ASEqualityHashHelpers.mm */; };
69708BA81D76386D005C3CF9 /* ASEqualityHashHelpers.mm in Sources */ = {isa = PBXBuildFile; fileRef = 69708BA51D76386D005C3CF9 /* ASEqualityHashHelpers.mm */; }; 69708BA81D76386D005C3CF9 /* ASEqualityHashHelpers.mm in Sources */ = {isa = PBXBuildFile; fileRef = 69708BA51D76386D005C3CF9 /* ASEqualityHashHelpers.mm */; };
6977965F1D8AC8D3007E93D7 /* ASLayoutSpec+Subclasses.h in Headers */ = {isa = PBXBuildFile; fileRef = 6977965D1D8AC8D3007E93D7 /* ASLayoutSpec+Subclasses.h */; };
697796601D8AC8D3007E93D7 /* ASLayoutSpec+Subclasses.mm in Sources */ = {isa = PBXBuildFile; fileRef = 6977965E1D8AC8D3007E93D7 /* ASLayoutSpec+Subclasses.mm */; };
697796611D8AC8D3007E93D7 /* ASLayoutSpec+Subclasses.mm in Sources */ = {isa = PBXBuildFile; fileRef = 6977965E1D8AC8D3007E93D7 /* ASLayoutSpec+Subclasses.mm */; };
697B315A1CFE4B410049936F /* ASEditableTextNodeTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 697B31591CFE4B410049936F /* ASEditableTextNodeTests.m */; }; 697B315A1CFE4B410049936F /* ASEditableTextNodeTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 697B31591CFE4B410049936F /* ASEditableTextNodeTests.m */; };
697C0DE41CF38F28001DE0D4 /* ASLayoutValidation.h in Headers */ = {isa = PBXBuildFile; fileRef = 697C0DE11CF38F28001DE0D4 /* ASLayoutValidation.h */; }; 697C0DE41CF38F28001DE0D4 /* ASLayoutValidation.h in Headers */ = {isa = PBXBuildFile; fileRef = 697C0DE11CF38F28001DE0D4 /* ASLayoutValidation.h */; };
697C0DE51CF38F28001DE0D4 /* ASLayoutValidation.mm in Sources */ = {isa = PBXBuildFile; fileRef = 697C0DE21CF38F28001DE0D4 /* ASLayoutValidation.mm */; }; 697C0DE51CF38F28001DE0D4 /* ASLayoutValidation.mm in Sources */ = {isa = PBXBuildFile; fileRef = 697C0DE21CF38F28001DE0D4 /* ASLayoutValidation.mm */; };
@@ -220,6 +223,7 @@
69E1006E1CA89CB600D88C1B /* ASEnvironmentInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 69E100691CA89CB600D88C1B /* ASEnvironmentInternal.h */; }; 69E1006E1CA89CB600D88C1B /* ASEnvironmentInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 69E100691CA89CB600D88C1B /* ASEnvironmentInternal.h */; };
69E1006F1CA89CB600D88C1B /* ASEnvironmentInternal.mm in Sources */ = {isa = PBXBuildFile; fileRef = 69E1006A1CA89CB600D88C1B /* ASEnvironmentInternal.mm */; }; 69E1006F1CA89CB600D88C1B /* ASEnvironmentInternal.mm in Sources */ = {isa = PBXBuildFile; fileRef = 69E1006A1CA89CB600D88C1B /* ASEnvironmentInternal.mm */; };
69E100701CA89CB600D88C1B /* ASEnvironmentInternal.mm in Sources */ = {isa = PBXBuildFile; fileRef = 69E1006A1CA89CB600D88C1B /* ASEnvironmentInternal.mm */; }; 69E100701CA89CB600D88C1B /* ASEnvironmentInternal.mm in Sources */ = {isa = PBXBuildFile; fileRef = 69E1006A1CA89CB600D88C1B /* ASEnvironmentInternal.mm */; };
69EEA0A11D9AB43900B46420 /* ASLayoutSpecPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 69EEA0A01D9AB43900B46420 /* ASLayoutSpecPrivate.h */; };
69F10C871C84C35D0026140C /* ASRangeControllerUpdateRangeProtocol+Beta.h in Headers */ = {isa = PBXBuildFile; fileRef = 69F10C851C84C35D0026140C /* ASRangeControllerUpdateRangeProtocol+Beta.h */; settings = {ATTRIBUTES = (Public, ); }; }; 69F10C871C84C35D0026140C /* ASRangeControllerUpdateRangeProtocol+Beta.h in Headers */ = {isa = PBXBuildFile; fileRef = 69F10C851C84C35D0026140C /* ASRangeControllerUpdateRangeProtocol+Beta.h */; settings = {ATTRIBUTES = (Public, ); }; };
69FEE53D1D95A9AF0086F066 /* ASLayoutableStyleTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 69FEE53C1D95A9AF0086F066 /* ASLayoutableStyleTests.m */; }; 69FEE53D1D95A9AF0086F066 /* ASLayoutableStyleTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 69FEE53C1D95A9AF0086F066 /* ASLayoutableStyleTests.m */; };
7630FFA81C9E267E007A7C0E /* ASVideoNode.h in Headers */ = {isa = PBXBuildFile; fileRef = AEEC47DF1C20C2DD00EC1693 /* ASVideoNode.h */; settings = {ATTRIBUTES = (Public, ); }; }; 7630FFA81C9E267E007A7C0E /* ASVideoNode.h in Headers */ = {isa = PBXBuildFile; fileRef = AEEC47DF1C20C2DD00EC1693 /* ASVideoNode.h */; settings = {ATTRIBUTES = (Public, ); }; };
@@ -985,6 +989,8 @@
696FCB301D6E46050093471E /* ASBackgroundLayoutSpecSnapshotTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASBackgroundLayoutSpecSnapshotTests.mm; sourceTree = "<group>"; }; 696FCB301D6E46050093471E /* ASBackgroundLayoutSpecSnapshotTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASBackgroundLayoutSpecSnapshotTests.mm; sourceTree = "<group>"; };
69708BA41D76386D005C3CF9 /* ASEqualityHashHelpers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ASEqualityHashHelpers.h; path = TextKit/ASEqualityHashHelpers.h; sourceTree = "<group>"; }; 69708BA41D76386D005C3CF9 /* ASEqualityHashHelpers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ASEqualityHashHelpers.h; path = TextKit/ASEqualityHashHelpers.h; sourceTree = "<group>"; };
69708BA51D76386D005C3CF9 /* ASEqualityHashHelpers.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = ASEqualityHashHelpers.mm; path = TextKit/ASEqualityHashHelpers.mm; sourceTree = "<group>"; }; 69708BA51D76386D005C3CF9 /* ASEqualityHashHelpers.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = ASEqualityHashHelpers.mm; path = TextKit/ASEqualityHashHelpers.mm; sourceTree = "<group>"; };
6977965D1D8AC8D3007E93D7 /* ASLayoutSpec+Subclasses.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "ASLayoutSpec+Subclasses.h"; path = "AsyncDisplayKit/Layout/ASLayoutSpec+Subclasses.h"; sourceTree = "<group>"; };
6977965E1D8AC8D3007E93D7 /* ASLayoutSpec+Subclasses.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = "ASLayoutSpec+Subclasses.mm"; path = "AsyncDisplayKit/Layout/ASLayoutSpec+Subclasses.mm"; sourceTree = "<group>"; };
697B31591CFE4B410049936F /* ASEditableTextNodeTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASEditableTextNodeTests.m; sourceTree = "<group>"; }; 697B31591CFE4B410049936F /* ASEditableTextNodeTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASEditableTextNodeTests.m; sourceTree = "<group>"; };
697C0DE11CF38F28001DE0D4 /* ASLayoutValidation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ASLayoutValidation.h; path = AsyncDisplayKit/Layout/ASLayoutValidation.h; sourceTree = "<group>"; }; 697C0DE11CF38F28001DE0D4 /* ASLayoutValidation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ASLayoutValidation.h; path = AsyncDisplayKit/Layout/ASLayoutValidation.h; sourceTree = "<group>"; };
697C0DE21CF38F28001DE0D4 /* ASLayoutValidation.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = ASLayoutValidation.mm; path = AsyncDisplayKit/Layout/ASLayoutValidation.mm; sourceTree = "<group>"; }; 697C0DE21CF38F28001DE0D4 /* ASLayoutValidation.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = ASLayoutValidation.mm; path = AsyncDisplayKit/Layout/ASLayoutValidation.mm; sourceTree = "<group>"; };
@@ -996,6 +1002,7 @@
69CB62AA1CB8165900024920 /* _ASDisplayViewAccessiblity.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = _ASDisplayViewAccessiblity.mm; sourceTree = "<group>"; }; 69CB62AA1CB8165900024920 /* _ASDisplayViewAccessiblity.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = _ASDisplayViewAccessiblity.mm; sourceTree = "<group>"; };
69E100691CA89CB600D88C1B /* ASEnvironmentInternal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASEnvironmentInternal.h; sourceTree = "<group>"; }; 69E100691CA89CB600D88C1B /* ASEnvironmentInternal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASEnvironmentInternal.h; sourceTree = "<group>"; };
69E1006A1CA89CB600D88C1B /* ASEnvironmentInternal.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASEnvironmentInternal.mm; sourceTree = "<group>"; }; 69E1006A1CA89CB600D88C1B /* ASEnvironmentInternal.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASEnvironmentInternal.mm; sourceTree = "<group>"; };
69EEA0A01D9AB43900B46420 /* ASLayoutSpecPrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASLayoutSpecPrivate.h; sourceTree = "<group>"; };
69F10C851C84C35D0026140C /* ASRangeControllerUpdateRangeProtocol+Beta.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "ASRangeControllerUpdateRangeProtocol+Beta.h"; sourceTree = "<group>"; }; 69F10C851C84C35D0026140C /* ASRangeControllerUpdateRangeProtocol+Beta.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "ASRangeControllerUpdateRangeProtocol+Beta.h"; sourceTree = "<group>"; };
69FEE53C1D95A9AF0086F066 /* ASLayoutableStyleTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASLayoutableStyleTests.m; sourceTree = "<group>"; }; 69FEE53C1D95A9AF0086F066 /* ASLayoutableStyleTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASLayoutableStyleTests.m; sourceTree = "<group>"; };
6BDC61F51978FEA400E50D21 /* AsyncDisplayKit.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; path = AsyncDisplayKit.h; sourceTree = "<group>"; }; 6BDC61F51978FEA400E50D21 /* AsyncDisplayKit.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; path = AsyncDisplayKit.h; sourceTree = "<group>"; };
@@ -1527,9 +1534,6 @@
058D0A01195D050800B7D73C /* Private */ = { 058D0A01195D050800B7D73C /* Private */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
CC446A2D1D80AAE00071FD03 /* ASObjectDescriptionHelpers.h */,
CC446A2E1D80AAE00071FD03 /* ASObjectDescriptionHelpers.m */,
CC54A81B1D70077A00296A24 /* ASDispatch.h */,
058D0A02195D050800B7D73C /* _AS-objc-internal.h */, 058D0A02195D050800B7D73C /* _AS-objc-internal.h */,
058D0A03195D050800B7D73C /* _ASCoreAnimationExtras.h */, 058D0A03195D050800B7D73C /* _ASCoreAnimationExtras.h */,
058D0A04195D050800B7D73C /* _ASCoreAnimationExtras.mm */, 058D0A04195D050800B7D73C /* _ASCoreAnimationExtras.mm */,
@@ -1548,6 +1552,7 @@
8B0768B21CE752EC002E1453 /* ASDefaultPlaybackButton.m */, 8B0768B21CE752EC002E1453 /* ASDefaultPlaybackButton.m */,
AEB7B0181C5962EA00662EF4 /* ASDefaultPlayButton.h */, AEB7B0181C5962EA00662EF4 /* ASDefaultPlayButton.h */,
AEB7B0191C5962EA00662EF4 /* ASDefaultPlayButton.m */, AEB7B0191C5962EA00662EF4 /* ASDefaultPlayButton.m */,
CC54A81B1D70077A00296A24 /* ASDispatch.h */,
058D0A08195D050800B7D73C /* ASDisplayNode+AsyncDisplay.mm */, 058D0A08195D050800B7D73C /* ASDisplayNode+AsyncDisplay.mm */,
058D0A09195D050800B7D73C /* ASDisplayNode+DebugTiming.h */, 058D0A09195D050800B7D73C /* ASDisplayNode+DebugTiming.h */,
058D0A0A195D050800B7D73C /* ASDisplayNode+DebugTiming.mm */, 058D0A0A195D050800B7D73C /* ASDisplayNode+DebugTiming.mm */,
@@ -1563,11 +1568,14 @@
058D0A0E195D050800B7D73C /* ASImageNode+CGExtras.m */, 058D0A0E195D050800B7D73C /* ASImageNode+CGExtras.m */,
ACF6ED431B17847A00DA7C62 /* ASInternalHelpers.h */, ACF6ED431B17847A00DA7C62 /* ASInternalHelpers.h */,
ACF6ED441B17847A00DA7C62 /* ASInternalHelpers.m */, ACF6ED441B17847A00DA7C62 /* ASInternalHelpers.m */,
69EEA0A01D9AB43900B46420 /* ASLayoutSpecPrivate.h */,
ACF6ED451B17847A00DA7C62 /* ASLayoutSpecUtilities.h */, ACF6ED451B17847A00DA7C62 /* ASLayoutSpecUtilities.h */,
E52405B41C8FEF16004DC8E7 /* ASLayoutTransition.h */, E52405B41C8FEF16004DC8E7 /* ASLayoutTransition.h */,
E52405B21C8FEF03004DC8E7 /* ASLayoutTransition.mm */, E52405B21C8FEF03004DC8E7 /* ASLayoutTransition.mm */,
0442850B1BAA64EC00D16268 /* ASMultidimensionalArrayUtils.h */, 0442850B1BAA64EC00D16268 /* ASMultidimensionalArrayUtils.h */,
0442850C1BAA64EC00D16268 /* ASMultidimensionalArrayUtils.mm */, 0442850C1BAA64EC00D16268 /* ASMultidimensionalArrayUtils.mm */,
CC446A2D1D80AAE00071FD03 /* ASObjectDescriptionHelpers.h */,
CC446A2E1D80AAE00071FD03 /* ASObjectDescriptionHelpers.m */,
CC3B20811C3F76D600798563 /* ASPendingStateController.h */, CC3B20811C3F76D600798563 /* ASPendingStateController.h */,
CC3B20821C3F76D600798563 /* ASPendingStateController.mm */, CC3B20821C3F76D600798563 /* ASPendingStateController.mm */,
058D0A10195D050800B7D73C /* ASSentinel.h */, 058D0A10195D050800B7D73C /* ASSentinel.h */,
@@ -1677,12 +1685,14 @@
ACF6ED0A1B17843500DA7C62 /* ASInsetLayoutSpec.mm */, ACF6ED0A1B17843500DA7C62 /* ASInsetLayoutSpec.mm */,
ACF6ED0B1B17843500DA7C62 /* ASLayout.h */, ACF6ED0B1B17843500DA7C62 /* ASLayout.h */,
ACF6ED0C1B17843500DA7C62 /* ASLayout.mm */, ACF6ED0C1B17843500DA7C62 /* ASLayout.mm */,
9CDC18CB1B910E12004965E2 /* ASLayoutablePrivate.h */,
ACF6ED111B17843500DA7C62 /* ASLayoutable.h */, ACF6ED111B17843500DA7C62 /* ASLayoutable.h */,
E55D86311CA8A14000A0C26F /* ASLayoutable.mm */, E55D86311CA8A14000A0C26F /* ASLayoutable.mm */,
698C8B601CAB49FC0052DC3F /* ASLayoutableExtensibility.h */, 698C8B601CAB49FC0052DC3F /* ASLayoutableExtensibility.h */,
9CDC18CB1B910E12004965E2 /* ASLayoutablePrivate.h */,
ACF6ED0D1B17843500DA7C62 /* ASLayoutSpec.h */, ACF6ED0D1B17843500DA7C62 /* ASLayoutSpec.h */,
ACF6ED0E1B17843500DA7C62 /* ASLayoutSpec.mm */, ACF6ED0E1B17843500DA7C62 /* ASLayoutSpec.mm */,
6977965D1D8AC8D3007E93D7 /* ASLayoutSpec+Subclasses.h */,
6977965E1D8AC8D3007E93D7 /* ASLayoutSpec+Subclasses.mm */,
697C0DE11CF38F28001DE0D4 /* ASLayoutValidation.h */, 697C0DE11CF38F28001DE0D4 /* ASLayoutValidation.h */,
697C0DE21CF38F28001DE0D4 /* ASLayoutValidation.mm */, 697C0DE21CF38F28001DE0D4 /* ASLayoutValidation.mm */,
ACF6ED121B17843500DA7C62 /* ASOverlayLayoutSpec.h */, ACF6ED121B17843500DA7C62 /* ASOverlayLayoutSpec.h */,
@@ -1775,6 +1785,7 @@
254C6B7C1BF94DF4003EC431 /* ASTextKitRenderer+TextChecking.h in Headers */, 254C6B7C1BF94DF4003EC431 /* ASTextKitRenderer+TextChecking.h in Headers */,
34EFC7611B701C9C00AD841F /* ASBackgroundLayoutSpec.h in Headers */, 34EFC7611B701C9C00AD841F /* ASBackgroundLayoutSpec.h in Headers */,
68AF37DB1CBEF4D80077BF76 /* ASImageNode+AnimatedImagePrivate.h in Headers */, 68AF37DB1CBEF4D80077BF76 /* ASImageNode+AnimatedImagePrivate.h in Headers */,
69EEA0A11D9AB43900B46420 /* ASLayoutSpecPrivate.h in Headers */,
B35062591B010F070018CF92 /* ASBaseDefines.h in Headers */, B35062591B010F070018CF92 /* ASBaseDefines.h in Headers */,
B35062131B010EFD0018CF92 /* ASBasicImageDownloader.h in Headers */, B35062131B010EFD0018CF92 /* ASBasicImageDownloader.h in Headers */,
B35062461B010EFD0018CF92 /* ASBasicImageDownloaderInternal.h in Headers */, B35062461B010EFD0018CF92 /* ASBasicImageDownloaderInternal.h in Headers */,
@@ -1819,6 +1830,7 @@
AC7A2C181BDE11DF0093FE1A /* ASTableViewInternal.h in Headers */, AC7A2C181BDE11DF0093FE1A /* ASTableViewInternal.h in Headers */,
B35062531B010EFD0018CF92 /* ASImageNode+CGExtras.h in Headers */, B35062531B010EFD0018CF92 /* ASImageNode+CGExtras.h in Headers */,
254C6B7F1BF94DF4003EC431 /* ASTextKitTruncating.h in Headers */, 254C6B7F1BF94DF4003EC431 /* ASTextKitTruncating.h in Headers */,
6977965F1D8AC8D3007E93D7 /* ASLayoutSpec+Subclasses.h in Headers */,
7AB338671C55B3460055FDE8 /* ASRelativeLayoutSpec.h in Headers */, 7AB338671C55B3460055FDE8 /* ASRelativeLayoutSpec.h in Headers */,
B35062021B010EFD0018CF92 /* ASImageNode.h in Headers */, B35062021B010EFD0018CF92 /* ASImageNode.h in Headers */,
B350621F1B010EFD0018CF92 /* ASImageProtocols.h in Headers */, B350621F1B010EFD0018CF92 /* ASImageProtocols.h in Headers */,
@@ -2227,6 +2239,7 @@
205F0E221B376416007741D0 /* CGRect+ASConvenience.m in Sources */, 205F0E221B376416007741D0 /* CGRect+ASConvenience.m in Sources */,
257754B21BEE44CD00737CA5 /* ASTextKitShadower.mm in Sources */, 257754B21BEE44CD00737CA5 /* ASTextKitShadower.mm in Sources */,
9CFFC6BE1CCAC52B006A6476 /* ASEnvironment.mm in Sources */, 9CFFC6BE1CCAC52B006A6476 /* ASEnvironment.mm in Sources */,
697796601D8AC8D3007E93D7 /* ASLayoutSpec+Subclasses.mm in Sources */,
058D0A21195D050800B7D73C /* NSMutableAttributedString+TextKitAdditions.m in Sources */, 058D0A21195D050800B7D73C /* NSMutableAttributedString+TextKitAdditions.m in Sources */,
205F0E101B371875007741D0 /* UICollectionViewLayout+ASConvenience.m in Sources */, 205F0E101B371875007741D0 /* UICollectionViewLayout+ASConvenience.m in Sources */,
CC7FD9DF1BB5E962005CCB2B /* ASPhotosFrameworkImageRequest.m in Sources */, CC7FD9DF1BB5E962005CCB2B /* ASPhotosFrameworkImageRequest.m in Sources */,
@@ -2411,6 +2424,7 @@
254C6B871BF94F8A003EC431 /* ASTextKitEntityAttribute.m in Sources */, 254C6B871BF94F8A003EC431 /* ASTextKitEntityAttribute.m in Sources */,
34566CB31BC1213700715E6B /* ASPhotosFrameworkImageRequest.m in Sources */, 34566CB31BC1213700715E6B /* ASPhotosFrameworkImageRequest.m in Sources */,
254C6B831BF94F8A003EC431 /* ASTextKitCoreTextAdditions.m in Sources */, 254C6B831BF94F8A003EC431 /* ASTextKitCoreTextAdditions.m in Sources */,
697796611D8AC8D3007E93D7 /* ASLayoutSpec+Subclasses.mm in Sources */,
B350623B1B010EFD0018CF92 /* NSMutableAttributedString+TextKitAdditions.m in Sources */, B350623B1B010EFD0018CF92 /* NSMutableAttributedString+TextKitAdditions.m in Sources */,
044284FD1BAA365100D16268 /* UICollectionViewLayout+ASConvenience.m in Sources */, 044284FD1BAA365100D16268 /* UICollectionViewLayout+ASConvenience.m in Sources */,
254C6B8A1BF94F8A003EC431 /* ASTextKitRenderer+TextChecking.mm in Sources */, 254C6B8A1BF94F8A003EC431 /* ASTextKitRenderer+TextChecking.mm in Sources */,

View File

@@ -3364,6 +3364,13 @@ static const char *ASDisplayNodeDrawingPriorityKey = "ASDrawingPriority";
} }
} }
#pragma mark - NSFastEnumeration
- (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState *)state objects:(id __unsafe_unretained _Nullable [_Nonnull])buffer count:(NSUInteger)len
{
return [self.subnodes countByEnumeratingWithState:state objects:buffer count:len];
}
#pragma mark - ASEnvironment #pragma mark - ASEnvironment
- (ASEnvironmentState)environmentState - (ASEnvironmentState)environmentState

View File

@@ -17,11 +17,16 @@ NS_ASSUME_NONNULL_BEGIN
*/ */
@interface ASBackgroundLayoutSpec : ASLayoutSpec @interface ASBackgroundLayoutSpec : ASLayoutSpec
/**
* Background layoutable for this layout spec
*/
@property (nullable, nonatomic, strong) id<ASLayoutable> background; @property (nullable, nonatomic, strong) id<ASLayoutable> background;
/** /**
@param child A child that is laid out to determine the size of this spec. * Creates and returns an ASBackgroundLayoutSpec object
@param background A layoutable object that is laid out behind the child. If this is nil, the background is omitted. *
* @param child A child that is laid out to determine the size of this spec.
* @param background A layoutable object that is laid out behind the child. If this is nil, the background is omitted.
*/ */
+ (instancetype)backgroundLayoutSpecWithChild:(id<ASLayoutable>)child background:(nullable id<ASLayoutable>)background; + (instancetype)backgroundLayoutSpecWithChild:(id<ASLayoutable>)child background:(nullable id<ASLayoutable>)background;

View File

@@ -9,6 +9,7 @@
// //
#import "ASBackgroundLayoutSpec.h" #import "ASBackgroundLayoutSpec.h"
#import "ASLayoutSpec+Subclasses.h"
#import "ASAssert.h" #import "ASAssert.h"
#import "ASLayout.h" #import "ASLayout.h"
@@ -16,11 +17,17 @@
static NSUInteger const kForegroundChildIndex = 0; static NSUInteger const kForegroundChildIndex = 0;
static NSUInteger const kBackgroundChildIndex = 1; static NSUInteger const kBackgroundChildIndex = 1;
@interface ASBackgroundLayoutSpec ()
@end
@implementation ASBackgroundLayoutSpec @implementation ASBackgroundLayoutSpec
#pragma mark - Class
+ (instancetype)backgroundLayoutSpecWithChild:(id<ASLayoutable>)child background:(id<ASLayoutable>)background;
{
return [[self alloc] initWithChild:child background:background];
}
#pragma mark - Lifecycle
- (instancetype)initWithChild:(id<ASLayoutable>)child background:(id<ASLayoutable>)background - (instancetype)initWithChild:(id<ASLayoutable>)child background:(id<ASLayoutable>)background
{ {
if (!(self = [super init])) { if (!(self = [super init])) {
@@ -28,15 +35,12 @@ static NSUInteger const kBackgroundChildIndex = 1;
} }
ASDisplayNodeAssertNotNil(child, @"Child cannot be nil"); ASDisplayNodeAssertNotNil(child, @"Child cannot be nil");
[self setChild:child forIndex:kForegroundChildIndex]; [self setChild:child atIndex:kForegroundChildIndex];
self.background = background; self.background = background;
return self; return self;
} }
+ (instancetype)backgroundLayoutSpecWithChild:(id<ASLayoutable>)child background:(id<ASLayoutable>)background; #pragma mark - ASLayoutSpec
{
return [[self alloc] initWithChild:child background:background];
}
/** /**
* First layout the contents, then fit the background image. * First layout the contents, then fit the background image.
@@ -45,7 +49,7 @@ static NSUInteger const kBackgroundChildIndex = 1;
restrictedToSize:(ASLayoutableSize)size restrictedToSize:(ASLayoutableSize)size
relativeToParentSize:(CGSize)parentSize relativeToParentSize:(CGSize)parentSize
{ {
ASLayout *contentsLayout = [self.child layoutThatFits:constrainedSize parentSize:parentSize]; ASLayout *contentsLayout = [[super childAtIndex:kForegroundChildIndex] layoutThatFits:constrainedSize parentSize:parentSize];
NSMutableArray *sublayouts = [NSMutableArray arrayWithCapacity:2]; NSMutableArray *sublayouts = [NSMutableArray arrayWithCapacity:2];
if (self.background) { if (self.background) {
@@ -61,14 +65,16 @@ static NSUInteger const kBackgroundChildIndex = 1;
return [ASLayout layoutWithLayoutable:self size:contentsLayout.size sublayouts:sublayouts]; return [ASLayout layoutWithLayoutable:self size:contentsLayout.size sublayouts:sublayouts];
} }
#pragma mark - Background
- (void)setBackground:(id<ASLayoutable>)background - (void)setBackground:(id<ASLayoutable>)background
{ {
[super setChild:background forIndex:kBackgroundChildIndex]; [super setChild:background atIndex:kBackgroundChildIndex];
} }
- (id<ASLayoutable>)background - (id<ASLayoutable>)background
{ {
return [super childForIndex:kBackgroundChildIndex]; return [super childAtIndex:kBackgroundChildIndex];
} }
@end @end

View File

@@ -0,0 +1,64 @@
//
// ASLayoutSpec+Subclasses.h
// AsyncDisplayKit
//
// Created by Michael Schneider on 9/15/16.
// Copyright © 2016 Facebook. All rights reserved.
//
#import <AsyncDisplayKit/AsyncDisplayKit.h>
NS_ASSUME_NONNULL_BEGIN
@interface ASLayoutSpec (Subclassing)
/**
* Helper method for finalLayoutable support
*
* @warning If you are getting recursion crashes here after implementing finalLayoutable, make sure
* that you are setting isFinalLayoutable flag to YES. This must be one BEFORE adding a child
* to the new ASLayoutable.
*
* For example:
* - (id<ASLayoutable>)finalLayoutable
* {
* ASInsetLayoutSpec *insetSpec = [[ASInsetLayoutSpec alloc] init];
* insetSpec.insets = UIEdgeInsetsMake(10,10,10,10);
* insetSpec.isFinalLayoutable = YES;
* [insetSpec setChild:self];
* return insetSpec;
* }
*
* @see finalLayoutable
*/
- (id<ASLayoutable>)layoutableToAddFromLayoutable:(id<ASLayoutable>)child;
/**
* Adds a child with the given identifier to this layout spec.
*
* @param child A child to be added.
*
* @param index An index associated with the child.
*
* @discussion Every ASLayoutSpec must act on at least one child. The ASLayoutSpec base class takes the
* responsibility of holding on to the spec children. Some layout specs, like ASInsetLayoutSpec,
* only require a single child.
*
* For layout specs that require a known number of children (ASBackgroundLayoutSpec, for example)
* a subclass can use the setChild method to set the "primary" child. It should then use this method
* to set any other required children. Ideally a subclass would hide this from the user, and use the
* setChild:forIndex: internally. For example, ASBackgroundLayoutSpec exposes a backgroundChild
* property that behind the scenes is calling setChild:forIndex:.
*/
- (void)setChild:(id<ASLayoutable>)child atIndex:(NSUInteger)index;
/**
* Returns the child added to this layout spec using the given index.
*
* @param index An identifier associated with the the child.
*/
- (nullable id<ASLayoutable>)childAtIndex:(NSUInteger)index;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,110 @@
//
// ASLayoutSpec+Subclasses.m
// AsyncDisplayKit
//
// Created by Michael Schneider on 9/15/16.
// Copyright © 2016 Facebook. All rights reserved.
//
#import "ASLayoutSpec+Subclasses.h"
#import "ASLayoutSpec.h"
#import "ASLayoutSpecPrivate.h"
#pragma mark - ASNullLayoutSpec
@interface ASNullLayoutSpec : ASLayoutSpec
- (instancetype)init __unavailable;
+ (ASNullLayoutSpec *)null;
@end
@implementation ASNullLayoutSpec : ASLayoutSpec
+ (ASNullLayoutSpec *)null
{
static ASNullLayoutSpec *sharedNullLayoutSpec = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedNullLayoutSpec = [[self alloc] init];
});
return sharedNullLayoutSpec;
}
- (BOOL)isMutable
{
return NO;
}
- (ASLayout *)calculateLayoutThatFits:(ASSizeRange)constrainedSize
{
return [ASLayout layoutWithLayoutable:self size:CGSizeZero];
}
@end
#pragma mark - ASLayoutSpec (Subclassing)
@implementation ASLayoutSpec (Subclassing)
#pragma mark - Final layoutable
- (id<ASLayoutable>)layoutableToAddFromLayoutable:(id<ASLayoutable>)child
{
if (self.isFinalLayoutable == NO) {
id<ASLayoutable> finalLayoutable = [child finalLayoutable];
if (finalLayoutable != child) {
if (ASEnvironmentStatePropagationEnabled()) {
ASEnvironmentStatePropagateUp(finalLayoutable, child.environmentState.layoutOptionsState);
} else {
// If state propagation is not enabled the layout options state needs to be copied manually
ASEnvironmentState finalLayoutableEnvironmentState = finalLayoutable.environmentState;
finalLayoutableEnvironmentState.layoutOptionsState = child.environmentState.layoutOptionsState;
finalLayoutable.environmentState = finalLayoutableEnvironmentState;
}
return finalLayoutable;
}
}
return child;
}
#pragma mark - Child with index
- (void)setChild:(id<ASLayoutable>)child atIndex:(NSUInteger)index
{
ASDisplayNodeAssert(self.isMutable, @"Cannot set properties when layout spec is not mutable");
id<ASLayoutable> layoutable = child ? [self layoutableToAddFromLayoutable:child] : [ASNullLayoutSpec null];
if (child) {
if (_childrenArray.count < index) {
// Fill up the array with null objects until the index
NSInteger i = _childrenArray.count;
while (i < index) {
_childrenArray[i] = [ASNullLayoutSpec null];
i++;
}
}
}
// Replace object at the given index with the layoutable
_childrenArray[index] = layoutable;
// TODO: Should we propagate up the layoutable at it could happen that multiple children will propagated up their
// layout options and one child will overwrite values from another child
// [self propagateUpLayoutable:finalLayoutable];
}
- (id<ASLayoutable>)childAtIndex:(NSUInteger)index
{
id<ASLayoutable> layoutable = nil;
if (index < _childrenArray.count) {
layoutable = _childrenArray[index];
}
// Null layoutable should not be accessed
ASDisplayNodeAssert(layoutable != [ASNullLayoutSpec null], @"Access child at index without set a child at that index");
return layoutable;
}
@end

View File

@@ -25,8 +25,6 @@ NS_ASSUME_NONNULL_BEGIN
*/ */
@property (nonatomic, assign) BOOL isMutable; @property (nonatomic, assign) BOOL isMutable;
- (instancetype)init;
/** /**
* Parent of the layout spec * Parent of the layout spec
*/ */
@@ -49,25 +47,6 @@ NS_ASSUME_NONNULL_BEGIN
*/ */
@property (nullable, strong, nonatomic) id<ASLayoutable> child; @property (nullable, strong, nonatomic) id<ASLayoutable> child;
/**
* Adds a child with the given identifier to this layout spec.
*
* @param child A child to be added.
*
* @param index An index associated with the child.
*
* @discussion Every ASLayoutSpec must act on at least one child. The ASLayoutSpec base class takes the
* responsibility of holding on to the spec children. Some layout specs, like ASInsetLayoutSpec,
* only require a single child.
*
* For layout specs that require a known number of children (ASBackgroundLayoutSpec, for example)
* a subclass can use the setChild method to set the "primary" child. It should then use this method
* to set any other required children. Ideally a subclass would hide this from the user, and use the
* setChild:forIndex: internally. For example, ASBackgroundLayoutSpec exposes a backgroundChild
* property that behind the scenes is calling setChild:forIndex:.
*/
- (void)setChild:(id<ASLayoutable>)child forIndex:(NSUInteger)index;
/** /**
* Adds childen to this layout spec. * Adds childen to this layout spec.
* *
@@ -81,13 +60,6 @@ NS_ASSUME_NONNULL_BEGIN
*/ */
@property (nullable, strong, nonatomic) NSArray<id<ASLayoutable>> *children; @property (nullable, strong, nonatomic) NSArray<id<ASLayoutable>> *children;
/**
* Returns the child added to this layout spec using the given index.
*
* @param index An identifier associated withe the child.
*/
- (nullable id<ASLayoutable>)childForIndex:(NSUInteger)index;
@end @end
/** /**
@@ -122,4 +94,3 @@ NS_ASSUME_NONNULL_BEGIN
@end @end
NS_ASSUME_NONNULL_END NS_ASSUME_NONNULL_END

View File

@@ -9,28 +9,8 @@
// //
#import "ASLayoutSpec.h" #import "ASLayoutSpec.h"
#import "ASLayoutSpecPrivate.h"
#import "ASAssert.h" #import "ASLayoutSpec+Subclasses.h"
#import "ASInternalHelpers.h"
#import "ASEnvironmentInternal.h"
#import "ASLayout.h"
#import "ASThread.h"
#import "ASTraitCollection.h"
#import <objc/runtime.h>
#import <map>
#import <vector>
typedef std::map<unsigned long, id<ASLayoutable>, std::less<unsigned long>> ASChildMap;
@interface ASLayoutSpec() {
ASDN::RecursiveMutex __instanceLock__;
ASChildMap _children;
ASEnvironmentState _environmentState;
ASLayoutableStyle *_style;
}
@end
@implementation ASLayoutSpec @implementation ASLayoutSpec
@@ -60,6 +40,7 @@ typedef std::map<unsigned long, id<ASLayoutable>, std::less<unsigned long>> ASCh
_isMutable = YES; _isMutable = YES;
_environmentState = ASEnvironmentStateMakeDefault(); _environmentState = ASEnvironmentStateMakeDefault();
_style = [[ASLayoutableStyle alloc] init]; _style = [[ASLayoutableStyle alloc] init];
_childrenArray = [[NSMutableArray alloc] init];
return self; return self;
} }
@@ -74,6 +55,13 @@ typedef std::map<unsigned long, id<ASLayoutable>, std::less<unsigned long>> ASCh
return YES; return YES;
} }
#pragma mark - Final Layoutable
- (id<ASLayoutable>)finalLayoutable
{
return self;
}
#pragma mark - Style #pragma mark - Style
- (ASLayoutableStyle *)style - (ASLayoutableStyle *)style
@@ -113,44 +101,8 @@ typedef std::map<unsigned long, id<ASLayoutable>, std::less<unsigned long>> ASCh
return [ASLayout layoutWithLayoutable:self size:constrainedSize.min]; return [ASLayout layoutWithLayoutable:self size:constrainedSize.min];
} }
- (id<ASLayoutable>)finalLayoutable
{
return self;
}
- (id<ASLayoutable>)layoutableToAddFromLayoutable:(id<ASLayoutable>)child #pragma mark - Parent
{
if (self.isFinalLayoutable == NO) {
// If you are getting recursion crashes here after implementing finalLayoutable, make sure
// that you are setting isFinalLayoutable flag to YES. This must be one BEFORE adding a child
// to the new ASLayoutable.
//
// For example:
//- (id<ASLayoutable>)finalLayoutable
//{
// ASInsetLayoutSpec *insetSpec = [[ASInsetLayoutSpec alloc] init];
// insetSpec.insets = UIEdgeInsetsMake(10,10,10,10);
// insetSpec.isFinalLayoutable = YES;
// [insetSpec setChild:self];
// return insetSpec;
//}
id<ASLayoutable> finalLayoutable = [child finalLayoutable];
if (finalLayoutable != child) {
if (ASEnvironmentStatePropagationEnabled()) {
ASEnvironmentStatePropagateUp(finalLayoutable, child.environmentState.layoutOptionsState);
} else {
// If state propagation is not enabled the layout options state needs to be copied manually
ASEnvironmentState finalLayoutableEnvironmentState = finalLayoutable.environmentState;
finalLayoutableEnvironmentState.layoutOptionsState = child.environmentState.layoutOptionsState;
finalLayoutable.environmentState = finalLayoutableEnvironmentState;
}
return finalLayoutable;
}
}
return child;
}
- (void)setParent:(id<ASLayoutable>)parent - (void)setParent:(id<ASLayoutable>)parent
{ {
@@ -162,67 +114,63 @@ typedef std::map<unsigned long, id<ASLayoutable>, std::less<unsigned long>> ASCh
} }
} }
#pragma mark - Child
- (void)setChild:(id<ASLayoutable>)child - (void)setChild:(id<ASLayoutable>)child
{ {
ASDisplayNodeAssert(self.isMutable, @"Cannot set properties when layout spec is not mutable"); ASDisplayNodeAssert(self.isMutable, @"Cannot set properties when layout spec is not mutable");;
ASDisplayNodeAssert(_childrenArray.count < 2, @"This layout spec does not support more than one child. Use the setChildren: or the setChild:AtIndex: API");
if (child) { if (child) {
id<ASLayoutable> finalLayoutable = [self layoutableToAddFromLayoutable:child]; id<ASLayoutable> finalLayoutable = [self layoutableToAddFromLayoutable:child];
if (finalLayoutable) { if (finalLayoutable) {
_children[0] = finalLayoutable; _childrenArray[0] = finalLayoutable;
[self propagateUpLayoutable:finalLayoutable]; [self propagateUpLayoutable:finalLayoutable];
} }
} else { } else {
_children.erase(0); if (_childrenArray.count) {
[_childrenArray removeObjectAtIndex:0];
}
} }
} }
- (void)setChild:(id<ASLayoutable>)child forIndex:(NSUInteger)index - (id<ASLayoutable>)child
{ {
ASDisplayNodeAssert(self.isMutable, @"Cannot set properties when layout spec is not mutable"); ASDisplayNodeAssert(_childrenArray.count < 2, @"This layout spec does not support more than one child. Use the setChildren: or the setChild:AtIndex: API");
if (child) {
id<ASLayoutable> finalLayoutable = [self layoutableToAddFromLayoutable:child]; if (_childrenArray.count) {
_children[index] = finalLayoutable; return _childrenArray[0];
} else {
_children.erase(index);
} }
// TODO: Should we propagate up the layoutable at it could happen that multiple children will propagated up their
// layout options and one child will overwrite values from another child return nil;
// [self propagateUpLayoutable:finalLayoutable];
} }
#pragma mark - Children
- (void)setChildren:(NSArray<id<ASLayoutable>> *)children - (void)setChildren:(NSArray<id<ASLayoutable>> *)children
{ {
ASDisplayNodeAssert(self.isMutable, @"Cannot set properties when layout spec is not mutable"); ASDisplayNodeAssert(self.isMutable, @"Cannot set properties when layout spec is not mutable");
_children.clear(); [_childrenArray removeAllObjects];
NSUInteger i = 0; NSUInteger i = 0;
for (id<ASLayoutable> child in children) { for (id<ASLayoutable> child in children) {
_children[i] = [self layoutableToAddFromLayoutable:child]; _childrenArray[i] = [self layoutableToAddFromLayoutable:child];
i += 1; i += 1;
} }
} }
- (id<ASLayoutable>)childForIndex:(NSUInteger)index
{
if (index < _children.size()) {
return _children[index];
}
return nil;
}
- (id<ASLayoutable>)child
{
return _children[0];
}
- (NSArray *)children - (NSArray *)children
{ {
std::vector<ASLayout *> children; return [_childrenArray copy];
for (ASChildMap::iterator it = _children.begin(); it != _children.end(); ++it ) { }
children.push_back(it->second);
}
return [NSArray arrayWithObjects:&children[0] count:children.size()]; #pragma mark - NSFastEnumeration
- (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState *)state objects:(id __unsafe_unretained _Nullable [_Nonnull])buffer count:(NSUInteger)len
{
return [_childrenArray countByEnumeratingWithState:state objects:buffer count:len];
} }
#pragma mark - ASEnvironment #pragma mark - ASEnvironment
@@ -279,7 +227,6 @@ ASEnvironmentLayoutExtensibilityForwarding
@end @end
#pragma mark - ASWrapperLayoutSpec #pragma mark - ASWrapperLayoutSpec
@implementation ASWrapperLayoutSpec @implementation ASWrapperLayoutSpec

View File

@@ -50,7 +50,7 @@ NS_ASSUME_NONNULL_BEGIN
* access to the options via convenience properties. If you are creating custom layout spec, then you can * access to the options via convenience properties. If you are creating custom layout spec, then you can
* extend the backing layout options class to accommodate any new layout options. * extend the backing layout options class to accommodate any new layout options.
*/ */
@protocol ASLayoutable <ASEnvironment, ASLayoutablePrivate, ASLayoutableExtensibility> @protocol ASLayoutable <ASEnvironment, ASLayoutablePrivate, ASLayoutableExtensibility, NSFastEnumeration>
#pragma mark - Getter #pragma mark - Getter

View File

@@ -17,8 +17,17 @@ NS_ASSUME_NONNULL_BEGIN
*/ */
@interface ASOverlayLayoutSpec : ASLayoutSpec @interface ASOverlayLayoutSpec : ASLayoutSpec
/**
* Overlay layoutable of this layout spec
*/
@property (nullable, nonatomic, strong) id<ASLayoutable> overlay; @property (nullable, nonatomic, strong) id<ASLayoutable> overlay;
/**
* Creates and returns an ASOverlayLayoutSpec object with a given child and an layoutable that act as overlay.
*
* @param child A child that is laid out to determine the size of this spec.
* @param overlay A layoutable object that is laid out over the child. If this is nil, the overlay is omitted.
*/
+ (instancetype)overlayLayoutSpecWithChild:(id<ASLayoutable>)child overlay:(nullable id<ASLayoutable>)overlay; + (instancetype)overlayLayoutSpecWithChild:(id<ASLayoutable>)child overlay:(nullable id<ASLayoutable>)overlay;
@end @end

View File

@@ -9,6 +9,7 @@
// //
#import "ASOverlayLayoutSpec.h" #import "ASOverlayLayoutSpec.h"
#import "ASLayoutSpec+Subclasses.h"
#import "ASAssert.h" #import "ASAssert.h"
#import "ASLayout.h" #import "ASLayout.h"
@@ -18,32 +19,40 @@ static NSUInteger const kOverlayChildIndex = 1;
@implementation ASOverlayLayoutSpec @implementation ASOverlayLayoutSpec
- (instancetype)initWithChild:(id<ASLayoutable>)child overlay:(id<ASLayoutable>)overlay #pragma mark - Class
{
if (!(self = [super init])) {
return nil;
}
ASDisplayNodeAssertNotNil(child, @"Child that will be overlayed on shouldn't be nil");
self.overlay = overlay;
[self setChild:child forIndex:kUnderlayChildIndex];
return self;
}
+ (instancetype)overlayLayoutSpecWithChild:(id<ASLayoutable>)child overlay:(id<ASLayoutable>)overlay + (instancetype)overlayLayoutSpecWithChild:(id<ASLayoutable>)child overlay:(id<ASLayoutable>)overlay
{ {
return [[self alloc] initWithChild:child overlay:overlay]; return [[self alloc] initWithChild:child overlay:overlay];
} }
#pragma mark - Lifecycle
- (instancetype)initWithChild:(id<ASLayoutable>)child overlay:(id<ASLayoutable>)overlay
{
if (!(self = [super init])) {
return nil;
}
ASDisplayNodeAssertNotNil(child, @"Child that will be overlayed on shouldn't be nil");
[self setChild:child atIndex:kUnderlayChildIndex];
self.overlay = overlay;
return self;
}
#pragma mark - Setter / Getter
- (void)setOverlay:(id<ASLayoutable>)overlay - (void)setOverlay:(id<ASLayoutable>)overlay
{ {
[super setChild:overlay forIndex:kOverlayChildIndex]; [super setChild:overlay atIndex:kOverlayChildIndex];
} }
- (id<ASLayoutable>)overlay - (id<ASLayoutable>)overlay
{ {
return [super childForIndex:kOverlayChildIndex]; return [super childAtIndex:kOverlayChildIndex];
} }
#pragma mark - ASLayoutSpec
/** /**
First layout the contents, then fit the overlay on top of it. First layout the contents, then fit the overlay on top of it.
*/ */
@@ -51,7 +60,7 @@ static NSUInteger const kOverlayChildIndex = 1;
restrictedToSize:(ASLayoutableSize)size restrictedToSize:(ASLayoutableSize)size
relativeToParentSize:(CGSize)parentSize relativeToParentSize:(CGSize)parentSize
{ {
ASLayout *contentsLayout = [self.child layoutThatFits:constrainedSize parentSize:parentSize]; ASLayout *contentsLayout = [[super childAtIndex:kUnderlayChildIndex] layoutThatFits:constrainedSize parentSize:parentSize];
contentsLayout.position = CGPointZero; contentsLayout.position = CGPointZero;
NSMutableArray *sublayouts = [NSMutableArray arrayWithObject:contentsLayout]; NSMutableArray *sublayouts = [NSMutableArray arrayWithObject:contentsLayout];
if (self.overlay) { if (self.overlay) {

View File

@@ -0,0 +1,25 @@
//
// ASLayoutSpecPrivate.h
// AsyncDisplayKit
//
// Created by Michael Schneider on 9/15/16.
//
// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
// This source code is licensed under the BSD-style license found in the
// LICENSE file in the root directory of this source tree. An additional grant
// of patent rights can be found in the PATENTS file in the same directory.
//
#import "ASInternalHelpers.h"
#import "ASEnvironmentInternal.h"
#import "ASThread.h"
@interface ASLayoutSpec() {
ASDN::RecursiveMutex __instanceLock__;
ASEnvironmentState _environmentState;
ASLayoutableStyle *_style;
NSMutableArray *_childrenArray;
}
@end

View File

@@ -2070,4 +2070,24 @@ static bool stringContainsPointer(NSString *description, id p) {
#pragma clang diagnostic pop #pragma clang diagnostic pop
} }
- (void)testSubnodesFastEnumeration
{
DeclareNodeNamed(parentNode);
DeclareNodeNamed(a);
DeclareNodeNamed(b);
DeclareNodeNamed(c);
DeclareViewNamed(d);
NSArray *subnodes = @[a, b, c, d];
for (ASDisplayNode *node in subnodes) {
[parentNode addSubnode:node];
}
NSInteger i = 0;
for (ASDisplayNode *subnode in parentNode.subnodes) {
XCTAssertEqualObjects(subnode, subnodes[i]);
i++;
}
}
@end @end