Merge branch 'master' into update-objc

Conflicts:
	AsyncDisplayKit/ASCellNode.h
This commit is contained in:
Adlai Holler
2015-11-02 09:36:46 -08:00
39 changed files with 592 additions and 206 deletions

View File

@@ -10,14 +10,14 @@
044284FD1BAA365100D16268 /* UICollectionViewLayout+ASConvenience.m in Sources */ = {isa = PBXBuildFile; fileRef = 205F0E0E1B371875007741D0 /* UICollectionViewLayout+ASConvenience.m */; };
044284FE1BAA387800D16268 /* ASStackLayoutSpecUtilities.h in Headers */ = {isa = PBXBuildFile; fileRef = ACF6ED461B17847A00DA7C62 /* ASStackLayoutSpecUtilities.h */; };
044284FF1BAA3BD600D16268 /* UICollectionViewLayout+ASConvenience.h in Headers */ = {isa = PBXBuildFile; fileRef = 205F0E0D1B371875007741D0 /* UICollectionViewLayout+ASConvenience.h */; settings = {ATTRIBUTES = (Public, ); }; };
044285071BAA63FE00D16268 /* ASBatchFetching.h in Headers */ = {isa = PBXBuildFile; fileRef = 044285051BAA63FE00D16268 /* ASBatchFetching.h */; settings = {ASSET_TAGS = (); }; };
044285081BAA63FE00D16268 /* ASBatchFetching.h in Headers */ = {isa = PBXBuildFile; fileRef = 044285051BAA63FE00D16268 /* ASBatchFetching.h */; settings = {ASSET_TAGS = (); }; };
044285091BAA63FE00D16268 /* ASBatchFetching.m in Sources */ = {isa = PBXBuildFile; fileRef = 044285061BAA63FE00D16268 /* ASBatchFetching.m */; settings = {ASSET_TAGS = (); }; };
0442850A1BAA63FE00D16268 /* ASBatchFetching.m in Sources */ = {isa = PBXBuildFile; fileRef = 044285061BAA63FE00D16268 /* ASBatchFetching.m */; settings = {ASSET_TAGS = (); }; };
0442850D1BAA64EC00D16268 /* ASMultidimensionalArrayUtils.h in Headers */ = {isa = PBXBuildFile; fileRef = 0442850B1BAA64EC00D16268 /* ASMultidimensionalArrayUtils.h */; settings = {ASSET_TAGS = (); }; };
0442850E1BAA64EC00D16268 /* ASMultidimensionalArrayUtils.h in Headers */ = {isa = PBXBuildFile; fileRef = 0442850B1BAA64EC00D16268 /* ASMultidimensionalArrayUtils.h */; settings = {ASSET_TAGS = (); }; };
0442850F1BAA64EC00D16268 /* ASMultidimensionalArrayUtils.mm in Sources */ = {isa = PBXBuildFile; fileRef = 0442850C1BAA64EC00D16268 /* ASMultidimensionalArrayUtils.mm */; settings = {ASSET_TAGS = (); }; };
044285101BAA64EC00D16268 /* ASMultidimensionalArrayUtils.mm in Sources */ = {isa = PBXBuildFile; fileRef = 0442850C1BAA64EC00D16268 /* ASMultidimensionalArrayUtils.mm */; settings = {ASSET_TAGS = (); }; };
044285071BAA63FE00D16268 /* ASBatchFetching.h in Headers */ = {isa = PBXBuildFile; fileRef = 044285051BAA63FE00D16268 /* ASBatchFetching.h */; };
044285081BAA63FE00D16268 /* ASBatchFetching.h in Headers */ = {isa = PBXBuildFile; fileRef = 044285051BAA63FE00D16268 /* ASBatchFetching.h */; };
044285091BAA63FE00D16268 /* ASBatchFetching.m in Sources */ = {isa = PBXBuildFile; fileRef = 044285061BAA63FE00D16268 /* ASBatchFetching.m */; };
0442850A1BAA63FE00D16268 /* ASBatchFetching.m in Sources */ = {isa = PBXBuildFile; fileRef = 044285061BAA63FE00D16268 /* ASBatchFetching.m */; };
0442850D1BAA64EC00D16268 /* ASMultidimensionalArrayUtils.h in Headers */ = {isa = PBXBuildFile; fileRef = 0442850B1BAA64EC00D16268 /* ASMultidimensionalArrayUtils.h */; };
0442850E1BAA64EC00D16268 /* ASMultidimensionalArrayUtils.h in Headers */ = {isa = PBXBuildFile; fileRef = 0442850B1BAA64EC00D16268 /* ASMultidimensionalArrayUtils.h */; };
0442850F1BAA64EC00D16268 /* ASMultidimensionalArrayUtils.mm in Sources */ = {isa = PBXBuildFile; fileRef = 0442850C1BAA64EC00D16268 /* ASMultidimensionalArrayUtils.mm */; };
044285101BAA64EC00D16268 /* ASMultidimensionalArrayUtils.mm in Sources */ = {isa = PBXBuildFile; fileRef = 0442850C1BAA64EC00D16268 /* ASMultidimensionalArrayUtils.mm */; };
0515EA211A15769900BA8B9A /* Photos.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 051943141A1575670030A7D0 /* Photos.framework */; settings = {ATTRIBUTES = (Weak, ); }; };
0515EA221A1576A100BA8B9A /* AssetsLibrary.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 051943121A1575630030A7D0 /* AssetsLibrary.framework */; };
0516FA3C1A15563400B4EBED /* ASAvailability.h in Headers */ = {isa = PBXBuildFile; fileRef = 0516FA3A1A15563400B4EBED /* ASAvailability.h */; settings = {ATTRIBUTES = (Public, ); }; };
@@ -67,7 +67,6 @@
058D0A22195D050800B7D73C /* _ASAsyncTransaction.m in Sources */ = {isa = PBXBuildFile; fileRef = 058D09F9195D050800B7D73C /* _ASAsyncTransaction.m */; };
058D0A23195D050800B7D73C /* _ASAsyncTransactionContainer.m in Sources */ = {isa = PBXBuildFile; fileRef = 058D09FC195D050800B7D73C /* _ASAsyncTransactionContainer.m */; };
058D0A24195D050800B7D73C /* _ASAsyncTransactionGroup.m in Sources */ = {isa = PBXBuildFile; fileRef = 058D09FE195D050800B7D73C /* _ASAsyncTransactionGroup.m */; };
058D0A25195D050800B7D73C /* UIView+ASConvenience.m in Sources */ = {isa = PBXBuildFile; fileRef = 058D0A00195D050800B7D73C /* UIView+ASConvenience.m */; };
058D0A26195D050800B7D73C /* _ASCoreAnimationExtras.mm in Sources */ = {isa = PBXBuildFile; fileRef = 058D0A04195D050800B7D73C /* _ASCoreAnimationExtras.mm */; };
058D0A27195D050800B7D73C /* _ASPendingState.m in Sources */ = {isa = PBXBuildFile; fileRef = 058D0A06195D050800B7D73C /* _ASPendingState.m */; };
058D0A28195D050800B7D73C /* ASDisplayNode+AsyncDisplay.mm in Sources */ = {isa = PBXBuildFile; fileRef = 058D0A08195D050800B7D73C /* ASDisplayNode+AsyncDisplay.mm */; };
@@ -140,14 +139,14 @@
205F0E211B376416007741D0 /* CGRect+ASConvenience.h in Headers */ = {isa = PBXBuildFile; fileRef = 205F0E1F1B376416007741D0 /* CGRect+ASConvenience.h */; settings = {ATTRIBUTES = (Public, ); }; };
205F0E221B376416007741D0 /* CGRect+ASConvenience.m in Sources */ = {isa = PBXBuildFile; fileRef = 205F0E201B376416007741D0 /* CGRect+ASConvenience.m */; };
242995D31B29743C00090100 /* ASBasicImageDownloaderTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 242995D21B29743C00090100 /* ASBasicImageDownloaderTests.m */; };
251B8EF71BBB3D690087C538 /* ASCollectionDataController.h in Headers */ = {isa = PBXBuildFile; fileRef = 251B8EF21BBB3D690087C538 /* ASCollectionDataController.h */; settings = {ASSET_TAGS = (); }; };
251B8EF81BBB3D690087C538 /* ASCollectionDataController.mm in Sources */ = {isa = PBXBuildFile; fileRef = 251B8EF31BBB3D690087C538 /* ASCollectionDataController.mm */; settings = {ASSET_TAGS = (); }; };
251B8EF91BBB3D690087C538 /* ASCollectionViewFlowLayoutInspector.h in Headers */ = {isa = PBXBuildFile; fileRef = 251B8EF41BBB3D690087C538 /* ASCollectionViewFlowLayoutInspector.h */; settings = {ASSET_TAGS = (); }; };
251B8EFA1BBB3D690087C538 /* ASCollectionViewFlowLayoutInspector.m in Sources */ = {isa = PBXBuildFile; fileRef = 251B8EF51BBB3D690087C538 /* ASCollectionViewFlowLayoutInspector.m */; settings = {ASSET_TAGS = (); }; };
251B8EFB1BBB3D690087C538 /* ASDataController+Subclasses.h in Headers */ = {isa = PBXBuildFile; fileRef = 251B8EF61BBB3D690087C538 /* ASDataController+Subclasses.h */; settings = {ASSET_TAGS = (); }; };
2538B6F31BC5D2A2003CA0B4 /* ASCollectionViewFlowLayoutInspectorTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 2538B6F21BC5D2A2003CA0B4 /* ASCollectionViewFlowLayoutInspectorTests.m */; settings = {ASSET_TAGS = (); }; };
251B8EF71BBB3D690087C538 /* ASCollectionDataController.h in Headers */ = {isa = PBXBuildFile; fileRef = 251B8EF21BBB3D690087C538 /* ASCollectionDataController.h */; };
251B8EF81BBB3D690087C538 /* ASCollectionDataController.mm in Sources */ = {isa = PBXBuildFile; fileRef = 251B8EF31BBB3D690087C538 /* ASCollectionDataController.mm */; };
251B8EF91BBB3D690087C538 /* ASCollectionViewFlowLayoutInspector.h in Headers */ = {isa = PBXBuildFile; fileRef = 251B8EF41BBB3D690087C538 /* ASCollectionViewFlowLayoutInspector.h */; };
251B8EFA1BBB3D690087C538 /* ASCollectionViewFlowLayoutInspector.m in Sources */ = {isa = PBXBuildFile; fileRef = 251B8EF51BBB3D690087C538 /* ASCollectionViewFlowLayoutInspector.m */; };
251B8EFB1BBB3D690087C538 /* ASDataController+Subclasses.h in Headers */ = {isa = PBXBuildFile; fileRef = 251B8EF61BBB3D690087C538 /* ASDataController+Subclasses.h */; };
2538B6F31BC5D2A2003CA0B4 /* ASCollectionViewFlowLayoutInspectorTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 2538B6F21BC5D2A2003CA0B4 /* ASCollectionViewFlowLayoutInspectorTests.m */; };
2767E9411BB19BD600EA9B77 /* ASViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = ACC945A81BA9E7A0005E1FB8 /* ASViewController.h */; settings = {ATTRIBUTES = (Public, ); }; };
2767E9421BB19BD600EA9B77 /* ASViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = ACC945AA1BA9E7C1005E1FB8 /* ASViewController.m */; settings = {ASSET_TAGS = (); }; };
2767E9421BB19BD600EA9B77 /* ASViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = ACC945AA1BA9E7C1005E1FB8 /* ASViewController.m */; };
2911485C1A77147A005D0878 /* ASControlNodeTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 2911485B1A77147A005D0878 /* ASControlNodeTests.m */; };
291B63FB1AA53A7A000A71B3 /* ASScrollDirection.h in Headers */ = {isa = PBXBuildFile; fileRef = 296A0A311A951715005ACEAA /* ASScrollDirection.h */; settings = {ATTRIBUTES = (Public, ); }; };
292C599F1A956527007E5DD6 /* ASLayoutRangeType.h in Headers */ = {isa = PBXBuildFile; fileRef = 292C59991A956527007E5DD6 /* ASLayoutRangeType.h */; settings = {ATTRIBUTES = (Public, ); }; };
@@ -162,7 +161,7 @@
299DA1AA1A828D2900162D41 /* ASBatchContext.mm in Sources */ = {isa = PBXBuildFile; fileRef = 299DA1A81A828D2900162D41 /* ASBatchContext.mm */; };
29CDC2E21AAE70D000833CA4 /* ASBasicImageDownloaderContextTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 29CDC2E11AAE70D000833CA4 /* ASBasicImageDownloaderContextTests.m */; };
2C107F5B1BA9F54500F13DE5 /* AsyncDisplayKit.h in Headers */ = {isa = PBXBuildFile; fileRef = 6BDC61F51978FEA400E50D21 /* AsyncDisplayKit.h */; settings = {ATTRIBUTES = (Public, ); }; };
34566CB31BC1213700715E6B /* ASPhotosFrameworkImageRequest.m in Sources */ = {isa = PBXBuildFile; fileRef = CC7FD9DD1BB5E962005CCB2B /* ASPhotosFrameworkImageRequest.m */; settings = {ASSET_TAGS = (); }; };
34566CB31BC1213700715E6B /* ASPhotosFrameworkImageRequest.m in Sources */ = {isa = PBXBuildFile; fileRef = CC7FD9DD1BB5E962005CCB2B /* ASPhotosFrameworkImageRequest.m */; };
34EFC75B1B701BAF00AD841F /* ASDimension.h in Headers */ = {isa = PBXBuildFile; fileRef = ACF6ED071B17843500DA7C62 /* ASDimension.h */; settings = {ATTRIBUTES = (Public, ); }; };
34EFC75C1B701BD200AD841F /* ASDimension.mm in Sources */ = {isa = PBXBuildFile; fileRef = ACF6ED081B17843500DA7C62 /* ASDimension.mm */; };
34EFC75D1B701BE900AD841F /* ASInternalHelpers.h in Headers */ = {isa = PBXBuildFile; fileRef = ACF6ED431B17847A00DA7C62 /* ASInternalHelpers.h */; };
@@ -217,8 +216,8 @@
9C49C36F1B853957000B0DD5 /* ASStackLayoutable.h in Headers */ = {isa = PBXBuildFile; fileRef = 9C49C36E1B853957000B0DD5 /* ASStackLayoutable.h */; settings = {ATTRIBUTES = (Public, ); }; };
9C49C3701B853961000B0DD5 /* ASStackLayoutable.h in Headers */ = {isa = PBXBuildFile; fileRef = 9C49C36E1B853957000B0DD5 /* ASStackLayoutable.h */; settings = {ATTRIBUTES = (Public, ); }; };
9C5586691BD549CB00B50E3A /* ASAsciiArtBoxCreator.h in Headers */ = {isa = PBXBuildFile; fileRef = 9C5586671BD549CB00B50E3A /* ASAsciiArtBoxCreator.h */; settings = {ATTRIBUTES = (Public, ); }; };
9C55866A1BD549CB00B50E3A /* ASAsciiArtBoxCreator.m in Sources */ = {isa = PBXBuildFile; fileRef = 9C5586681BD549CB00B50E3A /* ASAsciiArtBoxCreator.m */; settings = {ASSET_TAGS = (); }; };
9C55866B1BD54A1900B50E3A /* ASAsciiArtBoxCreator.m in Sources */ = {isa = PBXBuildFile; fileRef = 9C5586681BD549CB00B50E3A /* ASAsciiArtBoxCreator.m */; settings = {ASSET_TAGS = (); }; };
9C55866A1BD549CB00B50E3A /* ASAsciiArtBoxCreator.m in Sources */ = {isa = PBXBuildFile; fileRef = 9C5586681BD549CB00B50E3A /* ASAsciiArtBoxCreator.m */; };
9C55866B1BD54A1900B50E3A /* ASAsciiArtBoxCreator.m in Sources */ = {isa = PBXBuildFile; fileRef = 9C5586681BD549CB00B50E3A /* ASAsciiArtBoxCreator.m */; };
9C55866C1BD54A3000B50E3A /* ASAsciiArtBoxCreator.h in Headers */ = {isa = PBXBuildFile; fileRef = 9C5586671BD549CB00B50E3A /* ASAsciiArtBoxCreator.h */; settings = {ATTRIBUTES = (Public, ); }; };
9C5FA3511B8F6ADF00A62714 /* ASLayoutOptions.h in Headers */ = {isa = PBXBuildFile; fileRef = 9C5FA34F1B8F6ADF00A62714 /* ASLayoutOptions.h */; settings = {ATTRIBUTES = (Public, ); }; };
9C5FA3521B8F6ADF00A62714 /* ASLayoutOptions.h in Headers */ = {isa = PBXBuildFile; fileRef = 9C5FA34F1B8F6ADF00A62714 /* ASLayoutOptions.h */; settings = {ATTRIBUTES = (Public, ); }; };
@@ -232,11 +231,12 @@
9C6BB3B31B8CC9C200F13F52 /* ASStaticLayoutable.h in Headers */ = {isa = PBXBuildFile; fileRef = 9C6BB3B01B8CC9C200F13F52 /* ASStaticLayoutable.h */; settings = {ATTRIBUTES = (Public, ); }; };
9C8221951BA237B80037F19A /* ASStackBaselinePositionedLayout.h in Headers */ = {isa = PBXBuildFile; fileRef = 9C8221931BA237B80037F19A /* ASStackBaselinePositionedLayout.h */; };
9C8221961BA237B80037F19A /* ASStackBaselinePositionedLayout.h in Headers */ = {isa = PBXBuildFile; fileRef = 9C8221931BA237B80037F19A /* ASStackBaselinePositionedLayout.h */; };
9C8221971BA237B80037F19A /* ASStackBaselinePositionedLayout.mm in Sources */ = {isa = PBXBuildFile; fileRef = 9C8221941BA237B80037F19A /* ASStackBaselinePositionedLayout.mm */; settings = {ASSET_TAGS = (); }; };
9C8221981BA237B80037F19A /* ASStackBaselinePositionedLayout.mm in Sources */ = {isa = PBXBuildFile; fileRef = 9C8221941BA237B80037F19A /* ASStackBaselinePositionedLayout.mm */; settings = {ASSET_TAGS = (); }; };
9C8221971BA237B80037F19A /* ASStackBaselinePositionedLayout.mm in Sources */ = {isa = PBXBuildFile; fileRef = 9C8221941BA237B80037F19A /* ASStackBaselinePositionedLayout.mm */; };
9C8221981BA237B80037F19A /* ASStackBaselinePositionedLayout.mm in Sources */ = {isa = PBXBuildFile; fileRef = 9C8221941BA237B80037F19A /* ASStackBaselinePositionedLayout.mm */; };
9CDC18CC1B910E12004965E2 /* ASLayoutablePrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 9CDC18CB1B910E12004965E2 /* ASLayoutablePrivate.h */; settings = {ATTRIBUTES = (Public, ); }; };
9CDC18CD1B910E12004965E2 /* ASLayoutablePrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 9CDC18CB1B910E12004965E2 /* ASLayoutablePrivate.h */; settings = {ATTRIBUTES = (Public, ); }; };
9F06E5CD1B4CAF4200F015D8 /* ASCollectionViewTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 9F06E5CC1B4CAF4200F015D8 /* ASCollectionViewTests.m */; };
AC026B581BD3F61800BBC17E /* ASStaticLayoutSpecSnapshotTests.m in Sources */ = {isa = PBXBuildFile; fileRef = AC026B571BD3F61800BBC17E /* ASStaticLayoutSpecSnapshotTests.m */; };
AC026B691BD57D6F00BBC17E /* ASChangeSetDataController.h in Headers */ = {isa = PBXBuildFile; fileRef = AC026B671BD57D6F00BBC17E /* ASChangeSetDataController.h */; settings = {ATTRIBUTES = (Public, ); }; };
AC026B6A1BD57D6F00BBC17E /* ASChangeSetDataController.h in Headers */ = {isa = PBXBuildFile; fileRef = AC026B671BD57D6F00BBC17E /* ASChangeSetDataController.h */; settings = {ATTRIBUTES = (Public, ); }; };
AC026B6B1BD57D6F00BBC17E /* ASChangeSetDataController.m in Sources */ = {isa = PBXBuildFile; fileRef = AC026B681BD57D6F00BBC17E /* ASChangeSetDataController.m */; };
@@ -245,7 +245,6 @@
AC026B701BD57DBF00BBC17E /* _ASHierarchyChangeSet.h in Headers */ = {isa = PBXBuildFile; fileRef = AC026B6D1BD57DBF00BBC17E /* _ASHierarchyChangeSet.h */; };
AC026B711BD57DBF00BBC17E /* _ASHierarchyChangeSet.m in Sources */ = {isa = PBXBuildFile; fileRef = AC026B6E1BD57DBF00BBC17E /* _ASHierarchyChangeSet.m */; };
AC026B721BD57DBF00BBC17E /* _ASHierarchyChangeSet.m in Sources */ = {isa = PBXBuildFile; fileRef = AC026B6E1BD57DBF00BBC17E /* _ASHierarchyChangeSet.m */; };
AC026B581BD3F61800BBC17E /* ASStaticLayoutSpecSnapshotTests.m in Sources */ = {isa = PBXBuildFile; fileRef = AC026B571BD3F61800BBC17E /* ASStaticLayoutSpecSnapshotTests.m */; };
AC21EC101B3D0BF600C8B19A /* ASStackLayoutDefines.h in Headers */ = {isa = PBXBuildFile; fileRef = AC21EC0F1B3D0BF600C8B19A /* ASStackLayoutDefines.h */; settings = {ATTRIBUTES = (Public, ); }; };
AC3C4A511A1139C100143C57 /* ASCollectionView.h in Headers */ = {isa = PBXBuildFile; fileRef = AC3C4A4F1A1139C100143C57 /* ASCollectionView.h */; settings = {ATTRIBUTES = (Public, ); }; };
AC3C4A521A1139C100143C57 /* ASCollectionView.mm in Sources */ = {isa = PBXBuildFile; fileRef = AC3C4A501A1139C100143C57 /* ASCollectionView.mm */; };
@@ -372,7 +371,6 @@
B35062411B010EFD0018CF92 /* _ASAsyncTransactionGroup.h in Headers */ = {isa = PBXBuildFile; fileRef = 058D09FD195D050800B7D73C /* _ASAsyncTransactionGroup.h */; settings = {ATTRIBUTES = (Public, ); }; };
B35062421B010EFD0018CF92 /* _ASAsyncTransactionGroup.m in Sources */ = {isa = PBXBuildFile; fileRef = 058D09FE195D050800B7D73C /* _ASAsyncTransactionGroup.m */; };
B35062431B010EFD0018CF92 /* UIView+ASConvenience.h in Headers */ = {isa = PBXBuildFile; fileRef = 058D09FF195D050800B7D73C /* UIView+ASConvenience.h */; settings = {ATTRIBUTES = (Public, ); }; };
B35062441B010EFD0018CF92 /* UIView+ASConvenience.m in Sources */ = {isa = PBXBuildFile; fileRef = 058D0A00195D050800B7D73C /* UIView+ASConvenience.m */; };
B35062461B010EFD0018CF92 /* ASBasicImageDownloaderInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 2967F9E11AB0A4CF0072E4AB /* ASBasicImageDownloaderInternal.h */; };
B35062481B010EFD0018CF92 /* _AS-objc-internal.h in Headers */ = {isa = PBXBuildFile; fileRef = 058D0A02195D050800B7D73C /* _AS-objc-internal.h */; };
B35062491B010EFD0018CF92 /* _ASCoreAnimationExtras.h in Headers */ = {isa = PBXBuildFile; fileRef = 058D0A03195D050800B7D73C /* _ASCoreAnimationExtras.h */; };
@@ -399,12 +397,16 @@
B350625E1B0111780018CF92 /* AssetsLibrary.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 051943121A1575630030A7D0 /* AssetsLibrary.framework */; };
B350625F1B0111800018CF92 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 058D09AF195D04C000B7D73C /* Foundation.framework */; };
CC7FD9DE1BB5E962005CCB2B /* ASPhotosFrameworkImageRequest.h in Headers */ = {isa = PBXBuildFile; fileRef = CC7FD9DC1BB5E962005CCB2B /* ASPhotosFrameworkImageRequest.h */; settings = {ATTRIBUTES = (Public, ); }; };
CC7FD9DF1BB5E962005CCB2B /* ASPhotosFrameworkImageRequest.m in Sources */ = {isa = PBXBuildFile; fileRef = CC7FD9DD1BB5E962005CCB2B /* ASPhotosFrameworkImageRequest.m */; settings = {ASSET_TAGS = (); }; };
CC7FD9E11BB5F750005CCB2B /* ASPhotosFrameworkImageRequestTests.m in Sources */ = {isa = PBXBuildFile; fileRef = CC7FD9E01BB5F750005CCB2B /* ASPhotosFrameworkImageRequestTests.m */; settings = {ASSET_TAGS = (); }; };
CC7FD9DF1BB5E962005CCB2B /* ASPhotosFrameworkImageRequest.m in Sources */ = {isa = PBXBuildFile; fileRef = CC7FD9DD1BB5E962005CCB2B /* ASPhotosFrameworkImageRequest.m */; };
CC7FD9E11BB5F750005CCB2B /* ASPhotosFrameworkImageRequestTests.m in Sources */ = {isa = PBXBuildFile; fileRef = CC7FD9E01BB5F750005CCB2B /* ASPhotosFrameworkImageRequestTests.m */; };
CC7FD9E21BB603FF005CCB2B /* ASPhotosFrameworkImageRequest.h in Headers */ = {isa = PBXBuildFile; fileRef = CC7FD9DC1BB5E962005CCB2B /* ASPhotosFrameworkImageRequest.h */; settings = {ATTRIBUTES = (Public, ); }; };
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 */; };
DECBD6E71BE56E1900CF4905 /* ASButtonNode.h in Headers */ = {isa = PBXBuildFile; fileRef = DECBD6E51BE56E1900CF4905 /* ASButtonNode.h */; settings = {ATTRIBUTES = (Public, ); }; };
DECBD6E81BE56E1900CF4905 /* ASButtonNode.h in Headers */ = {isa = PBXBuildFile; fileRef = DECBD6E51BE56E1900CF4905 /* ASButtonNode.h */; settings = {ATTRIBUTES = (Public, ); }; };
DECBD6E91BE56E1900CF4905 /* ASButtonNode.mm in Sources */ = {isa = PBXBuildFile; fileRef = DECBD6E61BE56E1900CF4905 /* ASButtonNode.mm */; };
DECBD6EA1BE56E1900CF4905 /* ASButtonNode.mm in Sources */ = {isa = PBXBuildFile; fileRef = DECBD6E61BE56E1900CF4905 /* ASButtonNode.mm */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
@@ -607,11 +609,11 @@
9C8221941BA237B80037F19A /* ASStackBaselinePositionedLayout.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASStackBaselinePositionedLayout.mm; sourceTree = "<group>"; };
9CDC18CB1B910E12004965E2 /* ASLayoutablePrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ASLayoutablePrivate.h; path = AsyncDisplayKit/Layout/ASLayoutablePrivate.h; sourceTree = "<group>"; };
9F06E5CC1B4CAF4200F015D8 /* ASCollectionViewTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASCollectionViewTests.m; sourceTree = "<group>"; };
AC026B571BD3F61800BBC17E /* ASStaticLayoutSpecSnapshotTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASStaticLayoutSpecSnapshotTests.m; sourceTree = "<group>"; };
AC026B671BD57D6F00BBC17E /* ASChangeSetDataController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASChangeSetDataController.h; sourceTree = "<group>"; };
AC026B681BD57D6F00BBC17E /* ASChangeSetDataController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASChangeSetDataController.m; sourceTree = "<group>"; };
AC026B6D1BD57DBF00BBC17E /* _ASHierarchyChangeSet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = _ASHierarchyChangeSet.h; sourceTree = "<group>"; };
AC026B6E1BD57DBF00BBC17E /* _ASHierarchyChangeSet.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = _ASHierarchyChangeSet.m; sourceTree = "<group>"; };
AC026B571BD3F61800BBC17E /* ASStaticLayoutSpecSnapshotTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASStaticLayoutSpecSnapshotTests.m; sourceTree = "<group>"; };
AC21EC0F1B3D0BF600C8B19A /* ASStackLayoutDefines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ASStackLayoutDefines.h; path = AsyncDisplayKit/Layout/ASStackLayoutDefines.h; sourceTree = "<group>"; };
AC3C4A4F1A1139C100143C57 /* ASCollectionView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASCollectionView.h; sourceTree = "<group>"; };
AC3C4A501A1139C100143C57 /* ASCollectionView.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASCollectionView.mm; sourceTree = "<group>"; };
@@ -667,6 +669,8 @@
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 = "<group>"; };
D785F6601A74327E00291744 /* ASScrollNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASScrollNode.h; sourceTree = "<group>"; };
D785F6611A74327E00291744 /* ASScrollNode.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASScrollNode.m; sourceTree = "<group>"; };
DECBD6E51BE56E1900CF4905 /* ASButtonNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASButtonNode.h; sourceTree = "<group>"; };
DECBD6E61BE56E1900CF4905 /* ASButtonNode.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASButtonNode.mm; sourceTree = "<group>"; };
EFA731F0396842FF8AB635EE /* libPods-AsyncDisplayKitTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-AsyncDisplayKitTests.a"; sourceTree = BUILT_PRODUCTS_DIR; };
FB07EABBCF28656C6297BC2D /* Pods-AsyncDisplayKitTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-AsyncDisplayKitTests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-AsyncDisplayKitTests/Pods-AsyncDisplayKitTests.debug.xcconfig"; sourceTree = "<group>"; };
/* End PBXFileReference section */
@@ -788,6 +792,8 @@
AC3C4A531A113EEC00143C57 /* ASCollectionViewProtocols.h */,
058D09D5195D050800B7D73C /* ASControlNode.h */,
058D09D6195D050800B7D73C /* ASControlNode.m */,
DECBD6E51BE56E1900CF4905 /* ASButtonNode.h */,
DECBD6E61BE56E1900CF4905 /* ASButtonNode.mm */,
058D09D7195D050800B7D73C /* ASControlNode+Subclasses.h */,
058D09D8195D050800B7D73C /* ASDisplayNode.h */,
058D09D9195D050800B7D73C /* ASDisplayNode.mm */,
@@ -1129,6 +1135,7 @@
05A6D05A19D0EB64002DD95E /* ASDealloc2MainObject.h in Headers */,
ACF6ED201B17843500DA7C62 /* ASDimension.h in Headers */,
058D0A78195D05F900B7D73C /* ASDisplayNode+DebugTiming.h in Headers */,
DECBD6E71BE56E1900CF4905 /* ASButtonNode.h in Headers */,
058D0A4C195D05CB00B7D73C /* ASDisplayNode+Subclasses.h in Headers */,
058D0A4A195D05CB00B7D73C /* ASDisplayNode.h in Headers */,
058D0A84195D060300B7D73C /* ASDisplayNodeExtraIvars.h in Headers */,
@@ -1267,6 +1274,7 @@
B350625C1B010F070018CF92 /* ASLog.h in Headers */,
0442850E1BAA64EC00D16268 /* ASMultidimensionalArrayUtils.h in Headers */,
B35062041B010EFD0018CF92 /* ASMultiplexImageNode.h in Headers */,
DECBD6E81BE56E1900CF4905 /* ASButtonNode.h in Headers */,
B35062241B010EFD0018CF92 /* ASMutableAttributedStringBuilder.h in Headers */,
B35062061B010EFD0018CF92 /* ASNetworkImageNode.h in Headers */,
34EFC76C1B701CED00AD841F /* ASOverlayLayoutSpec.h in Headers */,
@@ -1355,6 +1363,7 @@
058D09B9195D04C000B7D73C /* Frameworks */,
058D09BA195D04C000B7D73C /* Resources */,
3B9D88CDF51B429C8409E4B6 /* Copy Pods Resources */,
6CC5F540055A48FCA8C12BF5 /* Embed Pods Frameworks */,
);
buildRules = (
);
@@ -1391,7 +1400,7 @@
058D09A4195D04C000B7D73C /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 0510;
LastUpgradeCheck = 0710;
ORGANIZATIONNAME = Facebook;
TargetAttributes = {
057D02BE1AC0A66700C7AC3C = {
@@ -1484,6 +1493,21 @@
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-AsyncDisplayKitTests/Pods-AsyncDisplayKitTests-resources.sh\"\n";
showEnvVarsInLog = 0;
};
6CC5F540055A48FCA8C12BF5 /* Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "Embed Pods Frameworks";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-AsyncDisplayKitTests/Pods-AsyncDisplayKitTests-frameworks.sh\"\n";
showEnvVarsInLog = 0;
};
/* End PBXShellScriptBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
@@ -1541,6 +1565,7 @@
251B8EFA1BBB3D690087C538 /* ASCollectionViewFlowLayoutInspector.m in Sources */,
ACF6ED271B17843500DA7C62 /* ASLayoutSpec.mm in Sources */,
0516FA411A1563D200B4EBED /* ASMultiplexImageNode.mm in Sources */,
DECBD6E91BE56E1900CF4905 /* ASButtonNode.mm in Sources */,
058D0A1B195D050800B7D73C /* ASMutableAttributedStringBuilder.m in Sources */,
055B9FA91A1C154B00035D6D /* ASNetworkImageNode.mm in Sources */,
ACF6ED2C1B17843500DA7C62 /* ASOverlayLayoutSpec.mm in Sources */,
@@ -1657,6 +1682,7 @@
34EFC7681B701CDE00AD841F /* ASLayout.mm in Sources */,
9C5FA3541B8F6ADF00A62714 /* ASLayoutOptions.mm in Sources */,
9C5FA3601B90C9A500A62714 /* ASLayoutOptionsPrivate.mm in Sources */,
DECBD6EA1BE56E1900CF4905 /* ASButtonNode.mm in Sources */,
34EFC76B1B701CEB00AD841F /* ASLayoutSpec.mm in Sources */,
B35062051B010EFD0018CF92 /* ASMultiplexImageNode.mm in Sources */,
B35062251B010EFD0018CF92 /* ASMutableAttributedStringBuilder.m in Sources */,
@@ -1771,6 +1797,7 @@
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COPY_PHASE_STRIP = NO;
ENABLE_TESTABILITY = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_DYNAMIC_NO_PIC = NO;
GCC_GENERATE_TEST_COVERAGE_FILES = YES;

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0700"
LastUpgradeVersion = "0710"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0700"
LastUpgradeVersion = "0710"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"

View File

@@ -0,0 +1,40 @@
/* 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 <AsyncDisplayKit/AsyncDisplayKit.h>
typedef enum : NSUInteger {
ASButtonStateNormal,
ASButtonStateHighlighted,
ASButtonStateDisabled,
} ASButtonState;
@interface ASButtonNode : ASControlNode
@property (nonatomic, readonly) ASTextNode *titleNode;
@property (nonatomic, readonly) ASImageNode *imageNode;
/**
Spacing between image and title. Defaults to 8.0.
*/
@property (nonatomic, assign) CGFloat contentSpacing;
/**
Whether button should be laid out vertically (image on top of text) or horizontally (image to the left of text).
ASButton node does not yet support RTL but it should be fairly easy to implement.
Defaults to YES.
*/
@property (nonatomic, assign) BOOL laysOutHorizontally;
- (NSAttributedString *)attributedTitleForState:(ASButtonState)state;
- (void)setAttributedTitle:(NSAttributedString *)title forState:(ASButtonState)state;
- (UIImage *)imageForState:(ASButtonState)state;
- (void)setImage:(UIImage *)image forState:(ASButtonState)state;
@end

View File

@@ -0,0 +1,222 @@
/* 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 "ASButtonNode.h"
#import <AsyncDisplayKit/ASThread.h>
@interface ASButtonNode ()
{
ASDN::RecursiveMutex _propertyLock;
NSAttributedString *_normalAttributedTitle;
NSAttributedString *_highlightedAttributedTitle;
NSAttributedString *_disabledAttributedTitle;
UIImage *_normalImage;
UIImage *_highlightedImage;
UIImage *_disabledImage;
}
@end
@implementation ASButtonNode
@synthesize contentSpacing = _contentSpacing;
@synthesize laysOutHorizontally = _laysOutHorizontally;
- (instancetype)init
{
if (self = [super init]) {
_contentSpacing = 8.0;
_laysOutHorizontally = YES;
_titleNode = [[ASTextNode alloc] init];
_imageNode = [[ASImageNode alloc] init];
[self addSubnode:_titleNode];
[self addSubnode:_imageNode];
[self addTarget:self action:@selector(controlEventUpdated:) forControlEvents:ASControlNodeEventAllEvents];
}
return self;
}
- (void)controlEventUpdated:(ASControlNode *)node
{
[self updateImage];
[self updateTitle];
}
- (void)updateImage
{
ASDN::MutexLocker l(_propertyLock);
UIImage *newImage;
if (self.enabled == NO && _disabledImage) {
newImage = _disabledImage;
} else if (self.highlighted && _highlightedImage) {
newImage = _highlightedImage;
} else {
newImage = _normalImage;
}
if (newImage != self.imageNode.image) {
self.imageNode.image = newImage;
[self setNeedsLayout];
}
}
- (void)updateTitle
{
ASDN::MutexLocker l(_propertyLock);
NSAttributedString *newTitle;
if (self.enabled == NO && _disabledAttributedTitle) {
newTitle = _disabledAttributedTitle;
} else if (self.highlighted && _highlightedAttributedTitle) {
newTitle = _highlightedAttributedTitle;
} else {
newTitle = _normalAttributedTitle;
}
if (newTitle != self.titleNode.attributedString) {
self.titleNode.attributedString = newTitle;
[self setNeedsLayout];
}
}
- (CGFloat)contentSpacing
{
ASDN::MutexLocker l(_propertyLock);
return _contentSpacing;
}
- (void)setContentSpacing:(CGFloat)contentSpacing
{
ASDN::MutexLocker l(_propertyLock);
if (contentSpacing == _contentSpacing)
return;
_contentSpacing = contentSpacing;
[self setNeedsLayout];
}
- (BOOL)laysOutHorizontally
{
ASDN::MutexLocker l(_propertyLock);
return _laysOutHorizontally;
}
- (void)setLaysOutHorizontally:(BOOL)laysOutHorizontally
{
ASDN::MutexLocker l(_propertyLock);
if (laysOutHorizontally == _laysOutHorizontally)
return;
_laysOutHorizontally = laysOutHorizontally;
[self setNeedsLayout];
}
- (NSAttributedString *)attributedTitleForState:(ASButtonState)state
{
ASDN::MutexLocker l(_propertyLock);
switch (state) {
case ASButtonStateNormal:
return _normalAttributedTitle;
case ASButtonStateHighlighted:
return _highlightedAttributedTitle;
case ASButtonStateDisabled:
return _disabledAttributedTitle;
}
}
- (void)setAttributedTitle:(NSAttributedString *)title forState:(ASButtonState)state
{
ASDN::MutexLocker l(_propertyLock);
switch (state) {
case ASButtonStateNormal:
_normalAttributedTitle = [title copy];
break;
case ASButtonStateHighlighted:
_highlightedAttributedTitle = [title copy];
break;
case ASButtonStateDisabled:
_disabledAttributedTitle = [title copy];
break;
}
[self updateTitle];
}
- (UIImage *)imageForState:(ASButtonState)state
{
ASDN::MutexLocker l(_propertyLock);
switch (state) {
case ASButtonStateNormal:
return _normalImage;
case ASButtonStateHighlighted:
return _highlightedImage;
case ASButtonStateDisabled:
return _disabledImage;
}
}
- (void)setImage:(UIImage *)image forState:(ASButtonState)state
{
ASDN::MutexLocker l(_propertyLock);
switch (state) {
case ASButtonStateNormal:
_normalImage = image;
break;
case ASButtonStateHighlighted:
_highlightedImage = image;
break;
case ASButtonStateDisabled:
_disabledImage = image;
break;
}
[self updateImage];
}
- (ASLayoutSpec *)layoutSpecThatFits:(ASSizeRange)constrainedSize
{
ASStackLayoutSpec *stack = [[ASStackLayoutSpec alloc] init];
stack.direction = self.laysOutHorizontally ? ASStackLayoutDirectionHorizontal : ASStackLayoutDirectionVertical;
stack.spacing = self.contentSpacing;
stack.justifyContent = ASStackLayoutJustifyContentCenter;
stack.alignItems = ASStackLayoutAlignItemsCenter;
NSMutableArray *children = [[NSMutableArray alloc] initWithCapacity:2];
if (self.imageNode.image) {
[children addObject:self.imageNode];
}
if (self.titleNode.attributedString.length > 0) {
[children addObject:self.titleNode];
}
stack.children = children;
return stack;
}
- (void)layout
{
[super layout];
self.imageNode.hidden = self.imageNode.image == nil;
self.titleNode.hidden = self.titleNode.attributedString.length > 0 == NO;
}
@end

View File

@@ -10,6 +10,23 @@
NS_ASSUME_NONNULL_BEGIN
@class ASCellNode;
typedef NSUInteger ASCellNodeAnimation;
@protocol ASCellNodeLayoutDelegate <NSObject>
/**
* Notifies the delegate that the specified cell node has done a relayout.
* The notification is done on main thread.
*
* @param node A node informing the delegate about the relayout.
*
* @param suggestedAnimation A constant indicates how the delegate should animate. See UITableViewRowAnimation.
*/
- (void)node:(ASCellNode *)node didRelayoutWithSuggestedAnimation:(ASCellNodeAnimation)animation;
@end
/**
* Generic cell node. Subclass this instead of `ASDisplayNode` to use with `ASTableView` and `ASCollectionView`.
*/
@@ -54,6 +71,18 @@ NS_ASSUME_NONNULL_BEGIN
*/
@property (nonatomic, assign) BOOL highlighted;
/*
* A delegate to be notified (on main thread) after a relayout.
*/
@property (nonatomic, weak) id<ASCellNodeLayoutDelegate> layoutDelegate;
/*
* A constant that is passed to the delegate to indicate how a relayout is to be animated.
*
* @see UITableViewRowAnimation
*/
@property (nonatomic, assign) ASCellNodeAnimation relayoutAnimation;
/*
* ASCellNode must forward touch events in order for UITableView and UICollectionView tap handling to work. Overriding
* these methods (e.g. for highlighting) requires the super method be called.
@@ -63,6 +92,17 @@ NS_ASSUME_NONNULL_BEGIN
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event ASDISPLAYNODE_REQUIRES_SUPER;
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event ASDISPLAYNODE_REQUIRES_SUPER;
/**
* Marks the node as needing layout. Convenience for use whether the view / layer is loaded or not. Safe to call from a background thread.
*
* If this node was measured, calling this method triggers an internal relayout: the calculated layout is invalidated,
* and the supernode is notified or (if this node is the root one) a full measurement pass is executed using the old constrained size.
* The delegate will then be notified on main thread.
*
* This method can be called inside of an animation block (to animate all of the layout changes).
*/
- (void)setNeedsLayout;
@end

View File

@@ -8,6 +8,7 @@
#import "ASCellNode.h"
#import "ASInternalHelpers.h"
#import <AsyncDisplayKit/_ASDisplayView.h>
#import <AsyncDisplayKit/ASDisplayNode+Subclasses.h>
#import <AsyncDisplayKit/ASTextNode.h>
@@ -27,6 +28,7 @@
// use UITableViewCell defaults
_selectionStyle = UITableViewCellSelectionStyleDefault;
self.clipsToBounds = YES;
_relayoutAnimation = UITableViewRowAnimationAutomatic;
return self;
}
@@ -49,6 +51,18 @@
ASDisplayNodeAssert(!layerBacked, @"ASCellNode does not support layer-backing.");
}
- (void)setNeedsLayout
{
ASDisplayNodeAssertThreadAffinity(self);
[super setNeedsLayout];
if (_layoutDelegate != nil) {
ASPerformBlockOnMainThread(^{
[_layoutDelegate node:self didRelayoutWithSuggestedAnimation:_relayoutAnimation];
});
}
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
ASDisplayNodeAssertMainThread();
@@ -122,7 +136,7 @@ static const CGFloat kFontSize = 18.0f;
_text = [text copy];
_textNode.attributedString = [[NSAttributedString alloc] initWithString:_text
attributes:@{NSFontAttributeName: [UIFont systemFontOfSize:kFontSize]}];
[self setNeedsLayout];
}
@end

View File

@@ -225,16 +225,6 @@ NS_ASSUME_NONNULL_BEGIN
*/
- (void)reloadItemsAtIndexPaths:(NSArray<NSIndexPath *> *)indexPaths;
/**
* Relayouts the specified item.
*
* @param indexPath The index path identifying the item to relayout.
*
* @discussion This method must be called from the main thread. The relayout is excuted on main thread.
* The node of the specified item must be updated to cause layout changes before this method is called.
*/
- (void)relayoutItemAtIndexPath:(NSIndexPath *)indexPath;
/**
* Moves the item at a specified location to a destination location.
*

View File

@@ -12,7 +12,6 @@
#import "ASCollectionViewLayoutController.h"
#import "ASRangeController.h"
#import "ASCollectionDataController.h"
#import "ASDisplayNodeInternal.h"
#import "ASBatchFetching.h"
#import "UICollectionViewLayout+ASConvenience.h"
#import "ASInternalHelpers.h"
@@ -131,7 +130,7 @@ static BOOL _isInterceptedSelector(SEL sel)
#pragma mark -
#pragma mark ASCollectionView.
@interface ASCollectionView () <ASRangeControllerDelegate, ASDataControllerSource> {
@interface ASCollectionView () <ASRangeControllerDelegate, ASDataControllerSource, ASCellNodeLayoutDelegate> {
_ASCollectionViewProxy *_proxyDataSource;
_ASCollectionViewProxy *_proxyDelegate;
@@ -269,7 +268,7 @@ static BOOL _isInterceptedSelector(SEL sel)
- (void)reloadDataWithCompletion:(void (^)())completion
{
ASDisplayNodeAssert(self.asyncDelegate, @"ASCollectionView's asyncDelegate property must be set.");
ASDisplayNodePerformBlockOnMainThread(^{
ASPerformBlockOnMainThread(^{
_superIsPendingDataLoad = YES;
[super reloadData];
});
@@ -458,14 +457,6 @@ static BOOL _isInterceptedSelector(SEL sel)
[_dataController reloadRowsAtIndexPaths:indexPaths withAnimationOptions:kASCollectionViewAnimationNone];
}
- (void)relayoutItemAtIndexPath:(NSIndexPath *)indexPath
{
ASDisplayNodeAssertMainThread();
ASCellNode *node = [self nodeForItemAtIndexPath:indexPath];
[node setNeedsLayout];
[super reloadItemsAtIndexPaths:@[indexPath]];
}
- (void)moveItemAtIndexPath:(NSIndexPath *)indexPath toIndexPath:(NSIndexPath *)newIndexPath
{
ASDisplayNodeAssertMainThread();
@@ -664,6 +655,7 @@ static BOOL _isInterceptedSelector(SEL sel)
{
ASCellNode *node = [_asyncDataSource collectionView:self nodeForItemAtIndexPath:indexPath];
ASDisplayNodeAssert([node isKindOfClass:ASCellNode.class], @"invalid node class, expected ASCellNode");
node.layoutDelegate = self;
return node;
}
@@ -789,26 +781,14 @@ static BOOL _isInterceptedSelector(SEL sel)
}
return; // if the asyncDataSource has become invalid while we are processing, ignore this request to avoid crashes
}
BOOL animationsEnabled = NO;
if (!animated) {
animationsEnabled = [UIView areAnimationsEnabled];
[UIView setAnimationsEnabled:NO];
}
[super performBatchUpdates:^{
[_batchUpdateBlocks enumerateObjectsUsingBlock:^(dispatch_block_t block, NSUInteger idx, BOOL *stop) {
block();
}];
} completion:^(BOOL finished) {
if (!animated) {
[UIView setAnimationsEnabled:animationsEnabled];
}
if (completion) {
completion(finished);
}
}];
ASPerformBlockWithoutAnimation(!animated, ^{
[super performBatchUpdates:^{
for (dispatch_block_t block in _batchUpdateBlocks) {
block();
}
} completion:completion];
});
[_batchUpdateBlocks removeAllObjects];
_performingBatchUpdates = NO;
@@ -907,4 +887,15 @@ static BOOL _isInterceptedSelector(SEL sel)
}
}
#pragma mark - ASCellNodeDelegate
- (void)node:(ASCellNode *)node didRelayoutWithSuggestedAnimation:(ASCellNodeAnimation)animation
{
ASDisplayNodeAssertMainThread();
NSIndexPath *indexPath = [self indexPathForNode:node];
if (indexPath != nil) {
[super reloadItemsAtIndexPaths:@[indexPath]];
}
}
@end

View File

@@ -561,14 +561,6 @@ typedef void (^ASDisplayNodeDidLoadBlock)(ASDisplayNode *node);
*
* If this node was measured, calling this method triggers an internal relayout: the calculated layout is invalidated,
* and the supernode is notified or (if this node is the root one) a full measurement pass is executed using the old constrained size.
*
* Note: If the relayout causes a change in size of the root node that is attached to a container view,
* the container view must be notified to relayout.
* For ASTableView and ASCollectionView, instead of calling this method directly,
* it is recommended to call -relayoutRowAtIndexPath:withRowAnimation and -relayoutItemAtIndexPath: respectively.
*
* @see [ASTableView relayoutRowAtIndexPath:withRowAnimation:]
* @see [ASCollectionView relayoutItemAtIndexPath:]
*/
- (void)setNeedsLayout;

View File

@@ -57,17 +57,6 @@ BOOL ASDisplayNodeSubclassOverridesSelector(Class subclass, SEL selector)
return ASSubclassOverridesSelector([ASDisplayNode class], subclass, selector);
}
void ASDisplayNodePerformBlockOnMainThread(void (^block)())
{
if ([NSThread isMainThread]) {
block();
} else {
dispatch_async(dispatch_get_main_queue(), ^{
block();
});
}
}
void ASDisplayNodeRespectThreadAffinityOfNode(ASDisplayNode *node, void (^block)())
{
ASDisplayNodeCAssertNotNil(block, @"block is required");
@@ -79,7 +68,7 @@ void ASDisplayNodeRespectThreadAffinityOfNode(ASDisplayNode *node, void (^block)
// Hold the lock to avoid a race where the node gets loaded while the block is in-flight.
ASDN::MutexLocker l(node->_propertyLock);
if (node.nodeLoaded) {
ASDisplayNodePerformBlockOnMainThread(^{
ASPerformBlockOnMainThread(^{
block();
});
} else {

View File

@@ -60,6 +60,11 @@ NS_ASSUME_NONNULL_BEGIN
//! @abstract The text input mode used by the receiver's keyboard, if it is visible. This value is undefined if the receiver is not the first responder.
@property (nonatomic, readonly) UITextInputMode *textInputMode;
/*
@abstract The textContainerInset of both the placeholder and typed textView. This value defaults to UIEdgeInsetsZero.
*/
@property (nonatomic, readwrite) UIEdgeInsets textContainerInset;
/*
@abstract The returnKeyType of the keyboard. This value defaults to UIReturnKeyDefault.
*/

View File

@@ -78,7 +78,8 @@
_textKitComponents.layoutManager.delegate = self;
_wordKerner = [[ASTextNodeWordKerner alloc] init];
_returnKeyType = UIReturnKeyDefault;
_textContainerInset = UIEdgeInsetsZero;
// Create the placeholder scaffolding.
_placeholderTextKitComponents = [ASTextKitComponents componentsWithAttributedSeedString:nil textContainerSize:CGSizeZero];
_placeholderTextKitComponents.layoutManager.delegate = self;
@@ -122,7 +123,7 @@
textView.backgroundColor = nil;
textView.opaque = NO;
}
textView.textContainerInset = UIEdgeInsetsZero;
textView.textContainerInset = self.textContainerInset;
textView.clipsToBounds = NO; // We don't want selection handles cut off.
};
@@ -175,6 +176,15 @@
_placeholderTextKitComponents.textView.backgroundColor = backgroundColor;
}
- (void)setTextContainerInset:(UIEdgeInsets)textContainerInset
{
ASDN::MutexLocker l(_textKitLock);
_textContainerInset = textContainerInset;
_textKitComponents.textView.textContainerInset = textContainerInset;
_placeholderTextKitComponents.textView.textContainerInset = textContainerInset;
}
- (void)setOpaque:(BOOL)opaque
{
[super setOpaque:opaque];

View File

@@ -128,7 +128,7 @@
_image = image;
ASDN::MutexUnlocker u(_imageLock);
ASDisplayNodePerformBlockOnMainThread(^{
ASPerformBlockOnMainThread(^{
[self invalidateCalculatedLayout];
[self setNeedsDisplay];
});
@@ -306,7 +306,7 @@
// If we have an image to display, display it, respecting our recrop flag.
if (self.image)
{
ASDisplayNodePerformBlockOnMainThread(^{
ASPerformBlockOnMainThread(^{
if (recropImmediately)
[self displayImmediately];
else
@@ -334,7 +334,7 @@
BOOL isCroppingImage = ((boundsSize.width < imageSize.width) || (boundsSize.height < imageSize.height));
// Re-display if we need to.
ASDisplayNodePerformBlockOnMainThread(^{
ASPerformBlockOnMainThread(^{
if (self.nodeLoaded && self.contentMode == UIViewContentModeScaleAspectFill && isCroppingImage)
[self setNeedsDisplay];
});

View File

@@ -24,10 +24,10 @@ NS_ASSUME_NONNULL_BEGIN
@interface ASNetworkImageNode : ASImageNode
/**
* The designated initializer.
* The designated initializer. Cache and Downloader are WEAK references.
*
* @param cache The object that implements a cache of images for the image node.
* @param downloader The object that implements image downloading for the image node. Must not be nil.
* @param cache The object that implements a cache of images for the image node. Weak reference.
* @param downloader The object that implements image downloading for the image node. Must not be nil. Weak reference.
*
* @discussion If `cache` is nil, the receiver will not attempt to retrieve images from a cache before downloading them.
*

View File

@@ -16,8 +16,8 @@
@interface ASNetworkImageNode ()
{
ASDN::RecursiveMutex _lock;
id<ASImageCacheProtocol> _cache;
id<ASImageDownloaderProtocol> _downloader;
__weak id<ASImageCacheProtocol> _cache;
__weak id<ASImageDownloaderProtocol> _downloader;
// Only access any of these with _lock.
__weak id<ASNetworkImageNodeDelegate> _delegate;
@@ -51,7 +51,7 @@
- (instancetype)init
{
return [self initWithCache:nil downloader:[[ASBasicImageDownloader alloc] init]];
return [self initWithCache:nil downloader:[ASBasicImageDownloader sharedImageDownloader]];
}
- (void)dealloc

View File

@@ -215,18 +215,6 @@ NS_ASSUME_NONNULL_BEGIN
*/
- (void)reloadRowsAtIndexPaths:(NSArray<NSIndexPath *> *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation;
/**
* Relayouts the specified row using a given animation effect.
*
* @param indexPath The index path identifying the row to relayout.
*
* @param animation A constant that indicates how the relayout is to be animated. See UITableViewRowAnimation.
*
* @discussion This method must be called from the main thread. The relayout is excuted on main thread.
* The node of the specified row must be updated to cause layout changes before this method is called.
*/
- (void)relayoutRowAtIndexPath:(NSIndexPath *)indexPath withRowAnimation:(UITableViewRowAnimation)animation;
/**
* Moves the row at a specified location to a destination location.
*
@@ -255,7 +243,7 @@ NS_ASSUME_NONNULL_BEGIN
*
* @returns an indexPath for this cellNode
*/
- (NSIndexPath *)indexPathForNode:(ASCellNode *)cellNode;
- (nullable NSIndexPath *)indexPathForNode:(ASCellNode *)cellNode;
/**
* Similar to -visibleCells.

View File

@@ -14,7 +14,6 @@
#import "ASCollectionViewLayoutController.h"
#import "ASLayoutController.h"
#import "ASRangeController.h"
#import "ASDisplayNodeInternal.h"
#import "ASBatchFetching.h"
#import "ASInternalHelpers.h"
#import "ASLayout.h"
@@ -152,7 +151,7 @@ static BOOL _isInterceptedSelector(SEL sel)
#pragma mark -
#pragma mark ASTableView
@interface ASTableView () <ASRangeControllerDelegate, ASDataControllerSource, _ASTableViewCellDelegate> {
@interface ASTableView () <ASRangeControllerDelegate, ASDataControllerSource, _ASTableViewCellDelegate, ASCellNodeLayoutDelegate> {
_ASTableViewProxy *_proxyDataSource;
_ASTableViewProxy *_proxyDelegate;
@@ -180,26 +179,6 @@ static BOOL _isInterceptedSelector(SEL sel)
@implementation ASTableView
/**
@summary Conditionally performs UIView geometry changes in the given block without animation.
Used primarily to circumvent UITableView forcing insertion animations when explicitly told not to via
`UITableViewRowAnimationNone`. More info: https://github.com/facebook/AsyncDisplayKit/pull/445
@param withoutAnimation Set to `YES` to perform given block without animation
@param block Perform UIView geometry changes within the passed block
*/
void ASPerformBlockWithoutAnimation(BOOL withoutAnimation, void (^block)()) {
if (withoutAnimation) {
BOOL animationsEnabled = [UIView areAnimationsEnabled];
[UIView setAnimationsEnabled:NO];
block();
[UIView setAnimationsEnabled:animationsEnabled];
} else {
block();
}
}
+ (Class)dataControllerClass
{
return [ASChangeSetDataController class];
@@ -334,7 +313,7 @@ void ASPerformBlockWithoutAnimation(BOOL withoutAnimation, void (^block)()) {
- (void)reloadDataWithCompletion:(void (^)())completion
{
ASDisplayNodeAssert(self.asyncDelegate, @"ASTableView's asyncDelegate property must be set.");
ASDisplayNodePerformBlockOnMainThread(^{
ASPerformBlockOnMainThread(^{
[super reloadData];
});
[_dataController reloadDataWithAnimationOptions:UITableViewRowAnimationNone completion:completion];
@@ -477,14 +456,6 @@ void ASPerformBlockWithoutAnimation(BOOL withoutAnimation, void (^block)()) {
[_dataController reloadRowsAtIndexPaths:indexPaths withAnimationOptions:animation];
}
- (void)relayoutRowAtIndexPath:(NSIndexPath *)indexPath withRowAnimation:(UITableViewRowAnimation)animation
{
ASDisplayNodeAssertMainThread();
ASCellNode *node = [self nodeForRowAtIndexPath:indexPath];
[node setNeedsLayout];
[super reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:animation];
}
- (void)moveRowAtIndexPath:(NSIndexPath *)indexPath toIndexPath:(NSIndexPath *)newIndexPath
{
ASDisplayNodeAssertMainThread();
@@ -849,6 +820,7 @@ void ASPerformBlockWithoutAnimation(BOOL withoutAnimation, void (^block)()) {
{
ASCellNode *node = [_asyncDataSource tableView:self nodeForRowAtIndexPath:indexPath];
ASDisplayNodeAssert([node isKindOfClass:ASCellNode.class], @"invalid node class, expected ASCellNode");
node.layoutDelegate = self;
return node;
}
@@ -923,4 +895,15 @@ void ASPerformBlockWithoutAnimation(BOOL withoutAnimation, void (^block)()) {
}
}
#pragma mark - ASCellNodeDelegate
- (void)node:(ASCellNode *)node didRelayoutWithSuggestedAnimation:(ASCellNodeAnimation)animation
{
ASDisplayNodeAssertMainThread();
NSIndexPath *indexPath = [self indexPathForNode:node];
if (indexPath != nil) {
[super reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:(UITableViewRowAnimation)animation];
}
}
@end

View File

@@ -81,6 +81,15 @@ typedef NS_ENUM(NSUInteger, ASTextNodeHighlightStyle) {
#pragma mark - Placeholders
/**
* @abstract ASTextNode has a special placeholder behavior when placeholderEnabled is YES.
*
* @discussion Defaults to NO. When YES, it draws rectangles for each line of text,
* following the true shape of the text's wrapping. This visually mirrors the overall
* shape and weight of paragraphs, making the appearance of the finished text less jarring.
*/
@property (nonatomic, assign) BOOL placeholderEnabled;
/**
@abstract The placeholder color.
*/

View File

@@ -96,6 +96,7 @@ static NSString *ASTextNodeTruncationTokenAttributeName = @"ASTextNodeTruncation
UILongPressGestureRecognizer *_longPressGestureRecognizer;
}
@dynamic placeholderEnabled;
#pragma mark - NSObject
@@ -131,7 +132,8 @@ static NSString *ASTextNodeTruncationTokenAttributeName = @"ASTextNodeTruncation
_constrainedSize = CGSizeMake(-INFINITY, -INFINITY);
// Placeholders
self.placeholderEnabled = YES;
// Disabled by default in ASDisplayNode, but add a few options for those who toggle
// on the special placeholder behavior of ASTextNode.
_placeholderColor = ASDisplayNodeDefaultPlaceholderColor();
_placeholderInsets = UIEdgeInsetsMake(1.0, 0.0, 1.0, 0.0);
}
@@ -747,6 +749,8 @@ static NSString *ASTextNodeTruncationTokenAttributeName = @"ASTextNodeTruncation
- (UIImage *)placeholderImage
{
// FIXME: Replace this implementation with reusable CALayers that have .backgroundColor set.
// This would completely eliminate the memory and performance cost of the backing store.
CGSize size = self.calculatedSize;
UIGraphicsBeginImageContext(size);
[self.placeholderColor setFill];

View File

@@ -22,6 +22,15 @@ NS_ASSUME_NONNULL_BEGIN
- (instancetype)initWithNode:(ASDisplayNode *)node;
/**
* The constrained size used to measure the backing node.
*
* @discussion Defaults to providing a size range that uses the view controller view's bounds as
* both the min and max definitions. Override this method to provide a custom size range to the
* backing node.
*/
- (ASSizeRange)nodeConstrainedSize;
@end
NS_ASSUME_NONNULL_END

View File

@@ -40,9 +40,7 @@
- (void)viewWillLayoutSubviews
{
[super viewWillLayoutSubviews];
CGSize viewSize = self.view.bounds.size;
ASSizeRange constrainedSize = ASSizeRangeMake(viewSize, viewSize);
[_node measureWithSizeRange:constrainedSize];
[_node measureWithSizeRange:[self nodeConstrainedSize]];
}
- (void)viewDidLayoutSubviews
@@ -61,4 +59,12 @@
[_node recursivelyFetchData];
}
// MARK: - Layout Helpers
- (ASSizeRange)nodeConstrainedSize
{
CGSize viewSize = self.view.bounds.size;
return ASSizeRangeMake(viewSize, viewSize);
}
@end

View File

@@ -12,6 +12,7 @@
#import <AsyncDisplayKit/ASControlNode.h>
#import <AsyncDisplayKit/ASImageNode.h>
#import <AsyncDisplayKit/ASTextNode.h>
#import <AsyncDisplayKit/ASButtonNode.h>
#import <AsyncDisplayKit/ASEditableTextNode.h>

View File

@@ -15,6 +15,8 @@ NS_ASSUME_NONNULL_BEGIN
*/
@interface ASBasicImageDownloader : NSObject <ASImageDownloaderProtocol>
+ (instancetype)sharedImageDownloader;
@end
NS_ASSUME_NONNULL_END

View File

@@ -200,6 +200,16 @@ static const char *kContextKey = NSStringFromClass(ASBasicImageDownloaderContext
@implementation ASBasicImageDownloader
+ (instancetype)sharedImageDownloader
{
static ASBasicImageDownloader *sharedImageDownloader = nil;
static dispatch_once_t once = 0;
dispatch_once(&once, ^{
sharedImageDownloader = [[ASBasicImageDownloader alloc] init];
});
return sharedImageDownloader;
}
#pragma mark Lifecycle.
- (instancetype)init

View File

@@ -14,7 +14,7 @@
#import "ASCellNode.h"
#import "ASDisplayNode.h"
#import "ASMultidimensionalArrayUtils.h"
#import "ASDisplayNodeInternal.h"
#import "ASInternalHelpers.h"
#import "ASLayout.h"
//#define LOG(...) NSLog(__VA_ARGS__)
@@ -208,7 +208,7 @@ static void *kASSizingQueueContext = &kASSizingQueueContext;
// Deep copy is critical here, or future edits to the sub-arrays will pollute state between _editing and _complete on different threads.
NSMutableArray *completedNodes = (NSMutableArray *)ASMultidimensionalArrayDeepMutableCopy(editingNodes);
ASDisplayNodePerformBlockOnMainThread(^{
ASPerformBlockOnMainThread(^{
_completedNodes[kind] = completedNodes;
if (completionBlock) {
completionBlock(nodes, indexPaths);
@@ -227,7 +227,7 @@ static void *kASSizingQueueContext = &kASSizingQueueContext;
ASDeleteElementsInMultidimensionalArrayAtIndexPaths(editingNodes, indexPaths);
_editingNodes[kind] = editingNodes;
ASDisplayNodePerformBlockOnMainThread(^{
ASPerformBlockOnMainThread(^{
NSArray *nodes = ASFindElementsInMultidimensionalArrayAtIndexPaths(_completedNodes[kind], indexPaths);
ASDeleteElementsInMultidimensionalArrayAtIndexPaths(_completedNodes[kind], indexPaths);
if (completionBlock) {
@@ -250,7 +250,7 @@ static void *kASSizingQueueContext = &kASSizingQueueContext;
// Deep copy is critical here, or future edits to the sub-arrays will pollute state between _editing and _complete on different threads.
NSArray *sectionsForCompleted = (NSMutableArray *)ASMultidimensionalArrayDeepMutableCopy(sections);
ASDisplayNodePerformBlockOnMainThread(^{
ASPerformBlockOnMainThread(^{
[_completedNodes[kind] insertObjects:sectionsForCompleted atIndexes:indexSet];
if (completionBlock) {
completionBlock(sections, indexSet);
@@ -263,7 +263,7 @@ static void *kASSizingQueueContext = &kASSizingQueueContext;
if (indexSet.count == 0)
return;
[_editingNodes[kind] removeObjectsAtIndexes:indexSet];
ASDisplayNodePerformBlockOnMainThread(^{
ASPerformBlockOnMainThread(^{
[_completedNodes[kind] removeObjectsAtIndexes:indexSet];
if (completionBlock) {
completionBlock(indexSet);
@@ -512,7 +512,7 @@ static void *kASSizingQueueContext = &kASSizingQueueContext;
LOG(@"endUpdatesWithCompletion - beginning");
[_editingTransactionQueue addOperationWithBlock:^{
ASDisplayNodePerformBlockOnMainThread(^{
ASPerformBlockOnMainThread(^{
// Deep copy _completedNodes to _externalCompletedNodes.
// Any external queries from now on will be done on _externalCompletedNodes, to guarantee data consistency with the delegate.
_externalCompletedNodes = (NSMutableArray *)ASMultidimensionalArrayDeepMutableCopy(_completedNodes[ASDataControllerRowNodeKind]);
@@ -532,7 +532,7 @@ static void *kASSizingQueueContext = &kASSizingQueueContext;
[_pendingEditCommandBlocks removeAllObjects];
[_editingTransactionQueue addOperationWithBlock:^{
ASDisplayNodePerformBlockOnMainThread(^{
ASPerformBlockOnMainThread(^{
// Now that the transaction is done, _completedNodes can be accessed externally again.
_externalCompletedNodes = nil;
@@ -819,7 +819,7 @@ static void *kASSizingQueueContext = &kASSizingQueueContext;
// i.e there might be some nodes that were measured using the old constrained size but haven't been added to _completedNodes
// (see _layoutNodes:atIndexPaths:withAnimationOptions:).
[_editingTransactionQueue addOperationWithBlock:^{
ASDisplayNodePerformBlockOnMainThread(^{
ASPerformBlockOnMainThread(^{
for (NSString *kind in [_completedNodes keyEnumerator]) {
[self _relayoutNodesOfKind:kind];
}

View File

@@ -10,10 +10,10 @@
#import "ASAssert.h"
#import "ASDisplayNodeExtras.h"
#import "ASDisplayNodeInternal.h"
#import "ASMultiDimensionalArrayUtils.h"
#import "ASRangeHandlerRender.h"
#import "ASRangeHandlerPreload.h"
#import "ASInternalHelpers.h"
@interface ASRangeController () {
BOOL _rangeIsValid;
@@ -177,13 +177,13 @@
#pragma mark - ASDataControllerDelegete
- (void)dataControllerBeginUpdates:(ASDataController *)dataController {
ASDisplayNodePerformBlockOnMainThread(^{
ASPerformBlockOnMainThread(^{
[_delegate rangeControllerBeginUpdates:self];
});
}
- (void)dataController:(ASDataController *)dataController endUpdatesAnimated:(BOOL)animated completion:(void (^)(BOOL))completion {
ASDisplayNodePerformBlockOnMainThread(^{
ASPerformBlockOnMainThread(^{
[_delegate rangeController:self endUpdatesAnimated:animated completion:completion];
});
}
@@ -196,14 +196,14 @@
[nodeSizes addObject:[NSValue valueWithCGSize:node.calculatedSize]];
}];
ASDisplayNodePerformBlockOnMainThread(^{
ASPerformBlockOnMainThread(^{
_rangeIsValid = NO;
[_delegate rangeController:self didInsertNodes:nodes atIndexPaths:indexPaths withAnimationOptions:animationOptions];
});
}
- (void)dataController:(ASDataController *)dataController didDeleteNodes:(NSArray *)nodes atIndexPaths:(NSArray *)indexPaths withAnimationOptions:(ASDataControllerAnimationOptions)animationOptions {
ASDisplayNodePerformBlockOnMainThread(^{
ASPerformBlockOnMainThread(^{
_rangeIsValid = NO;
[_delegate rangeController:self didDeleteNodes:nodes atIndexPaths:indexPaths withAnimationOptions:animationOptions];
});
@@ -222,14 +222,14 @@
[sectionNodeSizes addObject:nodeSizes];
}];
ASDisplayNodePerformBlockOnMainThread(^{
ASPerformBlockOnMainThread(^{
_rangeIsValid = NO;
[_delegate rangeController:self didInsertSectionsAtIndexSet:indexSet withAnimationOptions:animationOptions];
});
}
- (void)dataController:(ASDataController *)dataController didDeleteSectionsAtIndexSet:(NSIndexSet *)indexSet withAnimationOptions:(ASDataControllerAnimationOptions)animationOptions {
ASDisplayNodePerformBlockOnMainThread(^{
ASPerformBlockOnMainThread(^{
_rangeIsValid = NO;
[_delegate rangeController:self didDeleteSectionsAtIndexSet:indexSet withAnimationOptions:animationOptions];
});

View File

@@ -58,6 +58,16 @@ NS_ASSUME_NONNULL_BEGIN
*/
+ (instancetype)stackLayoutSpecWithDirection:(ASStackLayoutDirection)direction spacing:(CGFloat)spacing justifyContent:(ASStackLayoutJustifyContent)justifyContent alignItems:(ASStackLayoutAlignItems)alignItems children:(NSArray<id<ASLayoutable>> *)children;
/**
* @return A stack layout spec with direction of ASStackLayoutDirectionVertical
**/
+ (instancetype)verticalStackLayoutSpec;
/**
* @return A stack layout spec with direction of ASStackLayoutDirectionHorizontal
**/
+ (instancetype)horizontalStackLayoutSpec;
@end
NS_ASSUME_NONNULL_END

View File

@@ -38,6 +38,20 @@
return [[self alloc] initWithDirection:direction spacing:spacing justifyContent:justifyContent alignItems:alignItems children:children];
}
+ (instancetype)verticalStackLayoutSpec
{
ASStackLayoutSpec *stackLayoutSpec = [[self alloc] init];
stackLayoutSpec.direction = ASStackLayoutDirectionVertical;
return stackLayoutSpec;
}
+ (instancetype)horizontalStackLayoutSpec
{
ASStackLayoutSpec *stackLayoutSpec = [[self alloc] init];
stackLayoutSpec.direction = ASStackLayoutDirectionHorizontal;
return stackLayoutSpec;
}
- (instancetype)initWithDirection:(ASStackLayoutDirection)direction spacing:(CGFloat)spacing justifyContent:(ASStackLayoutJustifyContent)justifyContent alignItems:(ASStackLayoutAlignItems)alignItems children:(NSArray *)children
{
if (!(self = [super init])) {

View File

@@ -85,7 +85,7 @@
return _getFromLayer(cornerRadius);
}
-(void)setCornerRadius:(CGFloat)newCornerRadius
- (void)setCornerRadius:(CGFloat)newCornerRadius
{
_bridge_prologue;
_setToLayer(cornerRadius, newCornerRadius);

View File

@@ -20,7 +20,6 @@
#import "ASLayoutOptions.h"
BOOL ASDisplayNodeSubclassOverridesSelector(Class subclass, SEL selector);
void ASDisplayNodePerformBlockOnMainThread(void (^block)());
void ASDisplayNodeRespectThreadAffinityOfNode(ASDisplayNode *node, void (^block)());
typedef NS_OPTIONS(NSUInteger, ASDisplayNodeMethodOverrides) {

View File

@@ -10,12 +10,14 @@
#include <CoreGraphics/CGBase.h>
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#import "ASBaseDefines.h"
ASDISPLAYNODE_EXTERN_C_BEGIN
BOOL ASSubclassOverridesSelector(Class superclass, Class subclass, SEL selector);
BOOL ASSubclassOverridesClassSelector(Class superclass, Class subclass, SEL selector);
void ASPerformBlockOnMainThread(void (^block)());
CGFloat ASScreenScale();
@@ -27,6 +29,23 @@ CGFloat ASRoundPixelValue(CGFloat f);
ASDISPLAYNODE_EXTERN_C_END
/**
@summary Conditionally performs UIView geometry changes in the given block without animation.
Used primarily to circumvent UITableView forcing insertion animations when explicitly told not to via
`UITableViewRowAnimationNone`. More info: https://github.com/facebook/AsyncDisplayKit/pull/445
@param withoutAnimation Set to `YES` to perform given block without animation
@param block Perform UIView geometry changes within the passed block
*/
ASDISPLAYNODE_INLINE void ASPerformBlockWithoutAnimation(BOOL withoutAnimation, void (^block)()) {
if (withoutAnimation) {
[UIView performWithoutAnimation:block];
} else {
block();
}
}
@interface NSIndexPath (ASInverseComparison)
- (NSComparisonResult)asdk_inverseCompare:(NSIndexPath *)otherIndexPath;
@end

View File

@@ -46,6 +46,17 @@ static void ASDispatchOnceOnMainThread(dispatch_once_t *predicate, dispatch_bloc
}
}
void ASPerformBlockOnMainThread(void (^block)())
{
if ([NSThread isMainThread]) {
block();
} else {
dispatch_async(dispatch_get_main_queue(), ^{
block();
});
}
}
CGFloat ASScreenScale()
{
static CGFloat _scale;

View File

@@ -185,22 +185,13 @@ static const CGFloat kInnerPadding = 10.0f;
- (void)toggleImageEnlargement
{
_isImageEnlarged = !_isImageEnlarged;
[self setNeedsLayout];
}
- (void)toggleNodesSwap
{
_swappedTextAndImage = !_swappedTextAndImage;
[UIView animateWithDuration:0.15 animations:^{
self.alpha = 0;
} completion:^(BOOL finished) {
[self setNeedsLayout];
[self.view layoutIfNeeded];
[UIView animateWithDuration:0.15 animations:^{
self.alpha = 1;
}];
}];
[self setNeedsLayout];
}
@end

View File

@@ -121,7 +121,6 @@ static const NSInteger kMaxLitterSize = 100; // max number of kitten cell
// Assume only kitten nodes are selectable (see -tableView:shouldHighlightRowAtIndexPath:).
KittenNode *node = (KittenNode *)[_tableView nodeForRowAtIndexPath:indexPath];
[node toggleImageEnlargement];
[_tableView relayoutRowAtIndexPath:indexPath withRowAnimation:UITableViewRowAnimationAutomatic];
}
- (ASCellNode *)tableView:(ASTableView *)tableView nodeForRowAtIndexPath:(NSIndexPath *)indexPath
@@ -166,8 +165,6 @@ static const NSInteger kMaxLitterSize = 100; // max number of kitten cell
- (void)tableView:(UITableView *)tableView willBeginBatchFetchWithContext:(ASBatchContext *)context
{
NSLog(@"adding kitties");
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
sleep(1);
dispatch_async(dispatch_get_main_queue(), ^{
@@ -189,8 +186,6 @@ static const NSInteger kMaxLitterSize = 100; // max number of kitten cell
[tableView insertRowsAtIndexPaths:indexPaths withRowAnimation:UITableViewRowAnimationFade];
[context completeBatchFetching:YES];
NSLog(@"kittens added");
});
});
}

View File

@@ -123,6 +123,7 @@
05E2127E19D4DB510098F589 /* Frameworks */,
05E2127F19D4DB510098F589 /* Resources */,
F012A6F39E0149F18F564F50 /* Copy Pods Resources */,
93B7780A33739EF25F20366B /* Embed Pods Frameworks */,
);
buildRules = (
);
@@ -179,6 +180,21 @@
/* End PBXResourcesBuildPhase section */
/* Begin PBXShellScriptBuildPhase section */
93B7780A33739EF25F20366B /* Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "Embed Pods Frameworks";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods/Pods-frameworks.sh\"\n";
showEnvVarsInLog = 0;
};
E080B80F89C34A25B3488E26 /* Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;

View File

@@ -11,7 +11,7 @@
@interface ScreenNode : ASDisplayNode
@property (nonatomic, strong) ASMultiplexImageNode *imageNode;
@property (nonatomic, strong) ASTextNode *textNode;
@property (nonatomic, strong) ASButtonNode *buttonNode;
- (void)start;
- (void)reload;

View File

@@ -31,11 +31,13 @@
// load low-quality images before high-quality images
_imageNode.downloadsIntermediateImages = YES;
// simple status label
_textNode = [[ASTextNode alloc] init];
// simple status label. Synchronous to avoid flicker / placeholder state when updating.
_buttonNode = [[ASButtonNode alloc] init];
[_buttonNode addTarget:self action:@selector(reload) forControlEvents:ASControlNodeEventTouchUpInside];
_buttonNode.titleNode.displaysAsynchronously = NO;
[self addSubnode:_imageNode];
[self addSubnode:_textNode];
[self addSubnode:_buttonNode];
return self;
}
@@ -43,11 +45,12 @@
- (void)start
{
[self setText:@"loading…"];
_textNode.userInteractionEnabled = NO;
_buttonNode.userInteractionEnabled = NO;
_imageNode.imageIdentifiers = @[ @"best", @"medium", @"worst" ]; // go!
}
- (void)reload {
- (void)reload
{
[self start];
[_imageNode reloadImageIdentifierSources];
}
@@ -57,18 +60,21 @@
NSDictionary *attributes = @{NSFontAttributeName: [UIFont fontWithName:@"HelveticaNeue-Light" size:22.0f]};
NSAttributedString *string = [[NSAttributedString alloc] initWithString:text
attributes:attributes];
_textNode.attributedString = string;
[_buttonNode setAttributedTitle:string forState:ASButtonStateNormal];
[self setNeedsLayout];
}
- (ASLayoutSpec *)layoutSpecThatFits:(ASSizeRange)constrainedSize
{
ASRatioLayoutSpec *imagePlaceholder = [ASRatioLayoutSpec ratioLayoutSpecWithRatio:1 child:_imageNode];
ASStackLayoutSpec *verticalStack = [ASStackLayoutSpec stackLayoutSpecWithDirection:ASStackLayoutDirectionVertical
spacing:10
justifyContent:ASStackLayoutJustifyContentCenter
alignItems:ASStackLayoutAlignItemsCenter
children:@[imagePlaceholder, _textNode]];
ASStackLayoutSpec *verticalStack = [[ASStackLayoutSpec alloc] init];
verticalStack.direction = ASStackLayoutDirectionVertical;
verticalStack.spacing = 10;
verticalStack.justifyContent = ASStackLayoutJustifyContentCenter;
verticalStack.alignItems = ASStackLayoutAlignItemsCenter;
verticalStack.children = @[imagePlaceholder, _buttonNode];
return [ASInsetLayoutSpec insetLayoutSpecWithInsets:UIEdgeInsetsMake(10, 10, 10, 10) child:verticalStack];
}
@@ -98,8 +104,8 @@
[self setText:[NSString stringWithFormat:@"loaded '%@'", imageIdentifier]];
if ([imageIdentifier isEqualToString:@"best"]) {
[self setText:[_textNode.attributedString.string stringByAppendingString:@". tap to reload"]];
_textNode.userInteractionEnabled = YES;
[self setText:[_buttonNode.titleNode.attributedString.string stringByAppendingString:@". tap to reload"]];
_buttonNode.userInteractionEnabled = YES;
}
}

View File

@@ -12,7 +12,8 @@
#import "ViewController.h"
#import "ScreenNode.h"
@interface ViewController() {
@interface ViewController()
{
ScreenNode *_screenNode;
}
@@ -28,10 +29,6 @@
_screenNode = node;
// tap to reload
UITapGestureRecognizer *gr = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(reload:)];
[_screenNode.textNode.view addGestureRecognizer:gr];
return self;
}
@@ -42,10 +39,6 @@
[super viewWillAppear:animated];
}
- (void)reload:(id)sender {
[_screenNode reload];
}
- (BOOL)prefersStatusBarHidden
{
return YES;