Revert "update from master/"

This reverts commit d7fde61e168b6594ca5d74836597b0aac0e83e9b.
This commit is contained in:
Hannah Trosi 2016-07-02 11:45:40 -07:00
parent d7fde61e16
commit 3080ee33cf
31 changed files with 354 additions and 586 deletions

View File

@ -256,9 +256,9 @@
68355B3A1CB57A5A001D4E68 /* ASPINRemoteImageDownloader.m in Sources */ = {isa = PBXBuildFile; fileRef = 68355B361CB57A5A001D4E68 /* ASPINRemoteImageDownloader.m */; }; 68355B3A1CB57A5A001D4E68 /* ASPINRemoteImageDownloader.m in Sources */ = {isa = PBXBuildFile; fileRef = 68355B361CB57A5A001D4E68 /* ASPINRemoteImageDownloader.m */; };
68355B3B1CB57A5A001D4E68 /* ASImageContainerProtocolCategories.h in Headers */ = {isa = PBXBuildFile; fileRef = 68355B371CB57A5A001D4E68 /* ASImageContainerProtocolCategories.h */; settings = {ATTRIBUTES = (Public, ); }; }; 68355B3B1CB57A5A001D4E68 /* ASImageContainerProtocolCategories.h in Headers */ = {isa = PBXBuildFile; fileRef = 68355B371CB57A5A001D4E68 /* ASImageContainerProtocolCategories.h */; settings = {ATTRIBUTES = (Public, ); }; };
68355B3C1CB57A5A001D4E68 /* ASImageContainerProtocolCategories.m in Sources */ = {isa = PBXBuildFile; fileRef = 68355B381CB57A5A001D4E68 /* ASImageContainerProtocolCategories.m */; }; 68355B3C1CB57A5A001D4E68 /* ASImageContainerProtocolCategories.m in Sources */ = {isa = PBXBuildFile; fileRef = 68355B381CB57A5A001D4E68 /* ASImageContainerProtocolCategories.m */; };
68355B3D1CB57A5A001D4E68 /* ASPINRemoteImageDownloader.h in Headers */ = {isa = PBXBuildFile; fileRef = 68355B391CB57A5A001D4E68 /* ASPINRemoteImageDownloader.h */; settings = {ATTRIBUTES = (Public, ); }; }; 68355B3D1CB57A5A001D4E68 /* ASPINRemoteImageDownloader.h in Headers */ = {isa = PBXBuildFile; fileRef = 68355B391CB57A5A001D4E68 /* ASPINRemoteImageDownloader.h */; };
68355B3E1CB57A60001D4E68 /* ASPINRemoteImageDownloader.m in Sources */ = {isa = PBXBuildFile; fileRef = 68355B361CB57A5A001D4E68 /* ASPINRemoteImageDownloader.m */; }; 68355B3E1CB57A60001D4E68 /* ASPINRemoteImageDownloader.m in Sources */ = {isa = PBXBuildFile; fileRef = 68355B361CB57A5A001D4E68 /* ASPINRemoteImageDownloader.m */; };
68355B3F1CB57A64001D4E68 /* ASPINRemoteImageDownloader.h in Headers */ = {isa = PBXBuildFile; fileRef = 68355B391CB57A5A001D4E68 /* ASPINRemoteImageDownloader.h */; settings = {ATTRIBUTES = (Public, ); }; }; 68355B3F1CB57A64001D4E68 /* ASPINRemoteImageDownloader.h in Headers */ = {isa = PBXBuildFile; fileRef = 68355B391CB57A5A001D4E68 /* ASPINRemoteImageDownloader.h */; };
68355B401CB57A69001D4E68 /* ASImageContainerProtocolCategories.m in Sources */ = {isa = PBXBuildFile; fileRef = 68355B381CB57A5A001D4E68 /* ASImageContainerProtocolCategories.m */; }; 68355B401CB57A69001D4E68 /* ASImageContainerProtocolCategories.m in Sources */ = {isa = PBXBuildFile; fileRef = 68355B381CB57A5A001D4E68 /* ASImageContainerProtocolCategories.m */; };
68355B411CB57A6C001D4E68 /* ASImageContainerProtocolCategories.h in Headers */ = {isa = PBXBuildFile; fileRef = 68355B371CB57A5A001D4E68 /* ASImageContainerProtocolCategories.h */; settings = {ATTRIBUTES = (Public, ); }; }; 68355B411CB57A6C001D4E68 /* ASImageContainerProtocolCategories.h in Headers */ = {isa = PBXBuildFile; fileRef = 68355B371CB57A5A001D4E68 /* ASImageContainerProtocolCategories.h */; settings = {ATTRIBUTES = (Public, ); }; };
68AF37DB1CBEF4D80077BF76 /* ASImageNode+AnimatedImagePrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 68B8A4DB1CBD911D007E4543 /* ASImageNode+AnimatedImagePrivate.h */; }; 68AF37DB1CBEF4D80077BF76 /* ASImageNode+AnimatedImagePrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 68B8A4DB1CBD911D007E4543 /* ASImageNode+AnimatedImagePrivate.h */; };
@ -368,7 +368,6 @@
9C8898BB1C738B9800D6B02E /* ASTextKitFontSizeAdjuster.mm in Sources */ = {isa = PBXBuildFile; fileRef = 9C8898BA1C738B9800D6B02E /* ASTextKitFontSizeAdjuster.mm */; }; 9C8898BB1C738B9800D6B02E /* ASTextKitFontSizeAdjuster.mm in Sources */ = {isa = PBXBuildFile; fileRef = 9C8898BA1C738B9800D6B02E /* ASTextKitFontSizeAdjuster.mm */; };
9C8898BC1C738BA800D6B02E /* ASTextKitFontSizeAdjuster.mm in Sources */ = {isa = PBXBuildFile; fileRef = 9C8898BA1C738B9800D6B02E /* ASTextKitFontSizeAdjuster.mm */; }; 9C8898BC1C738BA800D6B02E /* ASTextKitFontSizeAdjuster.mm in Sources */ = {isa = PBXBuildFile; fileRef = 9C8898BA1C738B9800D6B02E /* ASTextKitFontSizeAdjuster.mm */; };
9C8898BD1C738BB800D6B02E /* ASTextKitFontSizeAdjuster.h in Headers */ = {isa = PBXBuildFile; fileRef = A32FEDD31C501B6A004F642A /* ASTextKitFontSizeAdjuster.h */; }; 9C8898BD1C738BB800D6B02E /* ASTextKitFontSizeAdjuster.h in Headers */ = {isa = PBXBuildFile; fileRef = A32FEDD31C501B6A004F642A /* ASTextKitFontSizeAdjuster.h */; };
9CC606651D24DF9E006581A0 /* NSIndexSet+ASHelpers.m in Sources */ = {isa = PBXBuildFile; fileRef = CC4981BB1D1C7F65004E13CC /* NSIndexSet+ASHelpers.m */; };
9CDC18CC1B910E12004965E2 /* ASLayoutablePrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 9CDC18CB1B910E12004965E2 /* ASLayoutablePrivate.h */; settings = {ATTRIBUTES = (Public, ); }; }; 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, ); }; }; 9CDC18CD1B910E12004965E2 /* ASLayoutablePrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 9CDC18CB1B910E12004965E2 /* ASLayoutablePrivate.h */; settings = {ATTRIBUTES = (Public, ); }; };
9CFFC6BE1CCAC52B006A6476 /* ASEnvironment.mm in Sources */ = {isa = PBXBuildFile; fileRef = 9CFFC6BD1CCAC52B006A6476 /* ASEnvironment.mm */; }; 9CFFC6BE1CCAC52B006A6476 /* ASEnvironment.mm in Sources */ = {isa = PBXBuildFile; fileRef = 9CFFC6BD1CCAC52B006A6476 /* ASEnvironment.mm */; };
@ -547,13 +546,10 @@
CC3B208E1C3F7D0A00798563 /* ASWeakSetTests.m in Sources */ = {isa = PBXBuildFile; fileRef = CC3B208D1C3F7D0A00798563 /* ASWeakSetTests.m */; }; CC3B208E1C3F7D0A00798563 /* ASWeakSetTests.m in Sources */ = {isa = PBXBuildFile; fileRef = CC3B208D1C3F7D0A00798563 /* ASWeakSetTests.m */; };
CC3B20901C3F892D00798563 /* ASBridgedPropertiesTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = CC3B208F1C3F892D00798563 /* ASBridgedPropertiesTests.mm */; }; CC3B20901C3F892D00798563 /* ASBridgedPropertiesTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = CC3B208F1C3F892D00798563 /* ASBridgedPropertiesTests.mm */; };
CC4981B31D1A02BE004E13CC /* ASTableViewThrashTests.m in Sources */ = {isa = PBXBuildFile; fileRef = CC4981B21D1A02BE004E13CC /* ASTableViewThrashTests.m */; }; CC4981B31D1A02BE004E13CC /* ASTableViewThrashTests.m in Sources */ = {isa = PBXBuildFile; fileRef = CC4981B21D1A02BE004E13CC /* ASTableViewThrashTests.m */; };
CC4981BC1D1C7F65004E13CC /* NSIndexSet+ASHelpers.h in Headers */ = {isa = PBXBuildFile; fileRef = CC4981BA1D1C7F65004E13CC /* NSIndexSet+ASHelpers.h */; };
CC4981BD1D1C7F65004E13CC /* NSIndexSet+ASHelpers.m in Sources */ = {isa = PBXBuildFile; fileRef = CC4981BB1D1C7F65004E13CC /* NSIndexSet+ASHelpers.m */; };
CC7FD9DE1BB5E962005CCB2B /* ASPhotosFrameworkImageRequest.h in Headers */ = {isa = PBXBuildFile; fileRef = CC7FD9DC1BB5E962005CCB2B /* ASPhotosFrameworkImageRequest.h */; settings = {ATTRIBUTES = (Public, ); }; }; 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 */; }; CC7FD9DF1BB5E962005CCB2B /* ASPhotosFrameworkImageRequest.m in Sources */ = {isa = PBXBuildFile; fileRef = CC7FD9DD1BB5E962005CCB2B /* ASPhotosFrameworkImageRequest.m */; };
CC7FD9E11BB5F750005CCB2B /* ASPhotosFrameworkImageRequestTests.m in Sources */ = {isa = PBXBuildFile; fileRef = CC7FD9E01BB5F750005CCB2B /* ASPhotosFrameworkImageRequestTests.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, ); }; }; CC7FD9E21BB603FF005CCB2B /* ASPhotosFrameworkImageRequest.h in Headers */ = {isa = PBXBuildFile; fileRef = CC7FD9DC1BB5E962005CCB2B /* ASPhotosFrameworkImageRequest.h */; settings = {ATTRIBUTES = (Public, ); }; };
CCF18FF41D2575E300DF5895 /* NSIndexSet+ASHelpers.h in Headers */ = {isa = PBXBuildFile; fileRef = CC4981BA1D1C7F65004E13CC /* NSIndexSet+ASHelpers.h */; };
D785F6621A74327E00291744 /* ASScrollNode.h in Headers */ = {isa = PBXBuildFile; fileRef = D785F6601A74327E00291744 /* ASScrollNode.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 */; }; D785F6631A74327E00291744 /* ASScrollNode.m in Sources */ = {isa = PBXBuildFile; fileRef = D785F6611A74327E00291744 /* ASScrollNode.m */; };
DB55C2611C6408D6004EDCF5 /* _ASTransitionContext.h in Headers */ = {isa = PBXBuildFile; fileRef = DB55C25F1C6408D6004EDCF5 /* _ASTransitionContext.h */; }; DB55C2611C6408D6004EDCF5 /* _ASTransitionContext.h in Headers */ = {isa = PBXBuildFile; fileRef = DB55C25F1C6408D6004EDCF5 /* _ASTransitionContext.h */; };
@ -941,8 +937,6 @@
CC3B208D1C3F7D0A00798563 /* ASWeakSetTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASWeakSetTests.m; sourceTree = "<group>"; }; CC3B208D1C3F7D0A00798563 /* ASWeakSetTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASWeakSetTests.m; sourceTree = "<group>"; };
CC3B208F1C3F892D00798563 /* ASBridgedPropertiesTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASBridgedPropertiesTests.mm; sourceTree = "<group>"; }; CC3B208F1C3F892D00798563 /* ASBridgedPropertiesTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASBridgedPropertiesTests.mm; sourceTree = "<group>"; };
CC4981B21D1A02BE004E13CC /* ASTableViewThrashTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASTableViewThrashTests.m; sourceTree = "<group>"; }; CC4981B21D1A02BE004E13CC /* ASTableViewThrashTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASTableViewThrashTests.m; sourceTree = "<group>"; };
CC4981BA1D1C7F65004E13CC /* NSIndexSet+ASHelpers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSIndexSet+ASHelpers.h"; sourceTree = "<group>"; };
CC4981BB1D1C7F65004E13CC /* NSIndexSet+ASHelpers.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSIndexSet+ASHelpers.m"; sourceTree = "<group>"; };
CC7FD9DC1BB5E962005CCB2B /* ASPhotosFrameworkImageRequest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASPhotosFrameworkImageRequest.h; sourceTree = "<group>"; }; CC7FD9DC1BB5E962005CCB2B /* ASPhotosFrameworkImageRequest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASPhotosFrameworkImageRequest.h; sourceTree = "<group>"; };
CC7FD9DD1BB5E962005CCB2B /* ASPhotosFrameworkImageRequest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASPhotosFrameworkImageRequest.m; sourceTree = "<group>"; }; CC7FD9DD1BB5E962005CCB2B /* ASPhotosFrameworkImageRequest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASPhotosFrameworkImageRequest.m; sourceTree = "<group>"; };
CC7FD9E01BB5F750005CCB2B /* ASPhotosFrameworkImageRequestTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASPhotosFrameworkImageRequestTests.m; sourceTree = "<group>"; }; CC7FD9E01BB5F750005CCB2B /* ASPhotosFrameworkImageRequestTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASPhotosFrameworkImageRequestTests.m; sourceTree = "<group>"; };
@ -1235,8 +1229,6 @@
058D09E1195D050800B7D73C /* Details */ = { 058D09E1195D050800B7D73C /* Details */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
CC4981BA1D1C7F65004E13CC /* NSIndexSet+ASHelpers.h */,
CC4981BB1D1C7F65004E13CC /* NSIndexSet+ASHelpers.m */,
9CFFC6BD1CCAC52B006A6476 /* ASEnvironment.mm */, 9CFFC6BD1CCAC52B006A6476 /* ASEnvironment.mm */,
058D09E2195D050800B7D73C /* _ASDisplayLayer.h */, 058D09E2195D050800B7D73C /* _ASDisplayLayer.h */,
058D09E3195D050800B7D73C /* _ASDisplayLayer.mm */, 058D09E3195D050800B7D73C /* _ASDisplayLayer.mm */,
@ -1642,7 +1634,6 @@
ACF6ED2D1B17843500DA7C62 /* ASRatioLayoutSpec.h in Headers */, ACF6ED2D1B17843500DA7C62 /* ASRatioLayoutSpec.h in Headers */,
AC47D9451B3BB41900AAEE9D /* ASRelativeSize.h in Headers */, AC47D9451B3BB41900AAEE9D /* ASRelativeSize.h in Headers */,
291B63FB1AA53A7A000A71B3 /* ASScrollDirection.h in Headers */, 291B63FB1AA53A7A000A71B3 /* ASScrollDirection.h in Headers */,
CC4981BC1D1C7F65004E13CC /* NSIndexSet+ASHelpers.h in Headers */,
D785F6621A74327E00291744 /* ASScrollNode.h in Headers */, D785F6621A74327E00291744 /* ASScrollNode.h in Headers */,
058D0A7F195D05F900B7D73C /* ASSentinel.h in Headers */, 058D0A7F195D05F900B7D73C /* ASSentinel.h in Headers */,
9C8221951BA237B80037F19A /* ASStackBaselinePositionedLayout.h in Headers */, 9C8221951BA237B80037F19A /* ASStackBaselinePositionedLayout.h in Headers */,
@ -1801,7 +1792,6 @@
254C6B741BF94DF4003EC431 /* ASTextNodeWordKerner.h in Headers */, 254C6B741BF94DF4003EC431 /* ASTextNodeWordKerner.h in Headers */,
DB55C2671C641AE4004EDCF5 /* ASContextTransitioning.h in Headers */, DB55C2671C641AE4004EDCF5 /* ASContextTransitioning.h in Headers */,
68B0277B1C1A79D60041016B /* ASDisplayNode+Beta.h in Headers */, 68B0277B1C1A79D60041016B /* ASDisplayNode+Beta.h in Headers */,
CCF18FF41D2575E300DF5895 /* NSIndexSet+ASHelpers.h in Headers */,
B350622D1B010EFD0018CF92 /* ASScrollDirection.h in Headers */, B350622D1B010EFD0018CF92 /* ASScrollDirection.h in Headers */,
254C6B751BF94DF4003EC431 /* ASTextKitComponents.h in Headers */, 254C6B751BF94DF4003EC431 /* ASTextKitComponents.h in Headers */,
B35062081B010EFD0018CF92 /* ASScrollNode.h in Headers */, B35062081B010EFD0018CF92 /* ASScrollNode.h in Headers */,
@ -1884,12 +1874,12 @@
isa = PBXNativeTarget; isa = PBXNativeTarget;
buildConfigurationList = 058D09D2195D04C000B7D73C /* Build configuration list for PBXNativeTarget "AsyncDisplayKitTests" */; buildConfigurationList = 058D09D2195D04C000B7D73C /* Build configuration list for PBXNativeTarget "AsyncDisplayKitTests" */;
buildPhases = ( buildPhases = (
2E61B6A0DB0F436A9DDBE86F /* [CP] Check Pods Manifest.lock */, 2E61B6A0DB0F436A9DDBE86F /* 📦 Check Pods Manifest.lock */,
058D09B8195D04C000B7D73C /* Sources */, 058D09B8195D04C000B7D73C /* Sources */,
058D09B9195D04C000B7D73C /* Frameworks */, 058D09B9195D04C000B7D73C /* Frameworks */,
058D09BA195D04C000B7D73C /* Resources */, 058D09BA195D04C000B7D73C /* Resources */,
3B9D88CDF51B429C8409E4B6 /* [CP] Copy Pods Resources */, 3B9D88CDF51B429C8409E4B6 /* 📦 Copy Pods Resources */,
B130AB1AC0A1E5162E211C19 /* [CP] Embed Pods Frameworks */, B130AB1AC0A1E5162E211C19 /* 📦 Embed Pods Frameworks */,
); );
buildRules = ( buildRules = (
); );
@ -1990,14 +1980,14 @@
/* End PBXResourcesBuildPhase section */ /* End PBXResourcesBuildPhase section */
/* Begin PBXShellScriptBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */
2E61B6A0DB0F436A9DDBE86F /* [CP] Check Pods Manifest.lock */ = { 2E61B6A0DB0F436A9DDBE86F /* 📦 Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase; isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
); );
inputPaths = ( inputPaths = (
); );
name = "[CP] Check Pods Manifest.lock"; name = "📦 Check Pods Manifest.lock";
outputPaths = ( outputPaths = (
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
@ -2005,14 +1995,14 @@
shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [[ $? != 0 ]] ; then\n cat << EOM\nerror: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\nEOM\n exit 1\nfi\n"; shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [[ $? != 0 ]] ; then\n cat << EOM\nerror: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\nEOM\n exit 1\nfi\n";
showEnvVarsInLog = 0; showEnvVarsInLog = 0;
}; };
3B9D88CDF51B429C8409E4B6 /* [CP] Copy Pods Resources */ = { 3B9D88CDF51B429C8409E4B6 /* 📦 Copy Pods Resources */ = {
isa = PBXShellScriptBuildPhase; isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
); );
inputPaths = ( inputPaths = (
); );
name = "[CP] Copy Pods Resources"; name = "📦 Copy Pods Resources";
outputPaths = ( outputPaths = (
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
@ -2020,14 +2010,14 @@
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-AsyncDisplayKitTests/Pods-AsyncDisplayKitTests-resources.sh\"\n"; shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-AsyncDisplayKitTests/Pods-AsyncDisplayKitTests-resources.sh\"\n";
showEnvVarsInLog = 0; showEnvVarsInLog = 0;
}; };
B130AB1AC0A1E5162E211C19 /* [CP] Embed Pods Frameworks */ = { B130AB1AC0A1E5162E211C19 /* 📦 Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase; isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
); );
inputPaths = ( inputPaths = (
); );
name = "[CP] Embed Pods Frameworks"; name = "📦 Embed Pods Frameworks";
outputPaths = ( outputPaths = (
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
@ -2111,7 +2101,6 @@
ACF6ED4C1B17847A00DA7C62 /* ASInternalHelpers.mm in Sources */, ACF6ED4C1B17847A00DA7C62 /* ASInternalHelpers.mm in Sources */,
68FC85DF1CE29AB700EDD713 /* ASNavigationController.m in Sources */, 68FC85DF1CE29AB700EDD713 /* ASNavigationController.m in Sources */,
ACF6ED251B17843500DA7C62 /* ASLayout.mm in Sources */, ACF6ED251B17843500DA7C62 /* ASLayout.mm in Sources */,
CC4981BD1D1C7F65004E13CC /* NSIndexSet+ASHelpers.m in Sources */,
DB55C2631C6408D6004EDCF5 /* _ASTransitionContext.m in Sources */, DB55C2631C6408D6004EDCF5 /* _ASTransitionContext.m in Sources */,
92074A631CC8BA1900918F75 /* ASImageNode+tvOS.m in Sources */, 92074A631CC8BA1900918F75 /* ASImageNode+tvOS.m in Sources */,
251B8EFA1BBB3D690087C538 /* ASCollectionViewFlowLayoutInspector.m in Sources */, 251B8EFA1BBB3D690087C538 /* ASCollectionViewFlowLayoutInspector.m in Sources */,
@ -2277,7 +2266,6 @@
CC3B208C1C3F7A5400798563 /* ASWeakSet.m in Sources */, CC3B208C1C3F7A5400798563 /* ASWeakSet.m in Sources */,
B350621C1B010EFD0018CF92 /* ASFlowLayoutController.mm in Sources */, B350621C1B010EFD0018CF92 /* ASFlowLayoutController.mm in Sources */,
B350621E1B010EFD0018CF92 /* ASHighlightOverlayLayer.mm in Sources */, B350621E1B010EFD0018CF92 /* ASHighlightOverlayLayer.mm in Sources */,
9CC606651D24DF9E006581A0 /* NSIndexSet+ASHelpers.m in Sources */,
92074A641CC8BA1900918F75 /* ASImageNode+tvOS.m in Sources */, 92074A641CC8BA1900918F75 /* ASImageNode+tvOS.m in Sources */,
B35062541B010EFD0018CF92 /* ASImageNode+CGExtras.m in Sources */, B35062541B010EFD0018CF92 /* ASImageNode+CGExtras.m in Sources */,
68355B401CB57A69001D4E68 /* ASImageContainerProtocolCategories.m in Sources */, 68355B401CB57A69001D4E68 /* ASImageContainerProtocolCategories.m in Sources */,

View File

@ -15,7 +15,6 @@
#import "ASBackgroundLayoutSpec.h" #import "ASBackgroundLayoutSpec.h"
#import "ASInsetLayoutSpec.h" #import "ASInsetLayoutSpec.h"
#import "ASDisplayNode+Beta.h" #import "ASDisplayNode+Beta.h"
#import "ASStaticLayoutSpec.h"
@interface ASButtonNode () @interface ASButtonNode ()
{ {
@ -492,13 +491,9 @@
spec = [ASInsetLayoutSpec insetLayoutSpecWithInsets:contentEdgeInsets child:spec]; spec = [ASInsetLayoutSpec insetLayoutSpecWithInsets:contentEdgeInsets child:spec];
} }
if (CGSizeEqualToSize(self.preferredFrameSize, CGSizeZero) == NO) {
stack.sizeRange = ASRelativeSizeRangeMakeWithExactCGSize(self.preferredFrameSize);
spec = [ASStaticLayoutSpec staticLayoutSpecWithChildren:@[stack]];
}
if (_backgroundImageNode.image) { if (_backgroundImageNode.image) {
spec = [ASBackgroundLayoutSpec backgroundLayoutSpecWithChild:spec background:_backgroundImageNode]; spec = [ASBackgroundLayoutSpec backgroundLayoutSpecWithChild:spec
background:_backgroundImageNode];
} }
return spec; return spec;

View File

@ -430,22 +430,22 @@ static NSString * const kCellReuseIdentifier = @"_ASCollectionViewCell";
- (void)setTuningParameters:(ASRangeTuningParameters)tuningParameters forRangeType:(ASLayoutRangeType)rangeType - (void)setTuningParameters:(ASRangeTuningParameters)tuningParameters forRangeType:(ASLayoutRangeType)rangeType
{ {
[_rangeController setTuningParameters:tuningParameters forRangeMode:ASLayoutRangeModeFull rangeType:rangeType]; [_collectionNode setTuningParameters:tuningParameters forRangeType:rangeType];
} }
- (ASRangeTuningParameters)tuningParametersForRangeType:(ASLayoutRangeType)rangeType - (ASRangeTuningParameters)tuningParametersForRangeType:(ASLayoutRangeType)rangeType
{ {
return [_rangeController tuningParametersForRangeMode:ASLayoutRangeModeFull rangeType:rangeType]; return [_collectionNode tuningParametersForRangeType:rangeType];
} }
- (void)setTuningParameters:(ASRangeTuningParameters)tuningParameters forRangeMode:(ASLayoutRangeMode)rangeMode rangeType:(ASLayoutRangeType)rangeType - (void)setTuningParameters:(ASRangeTuningParameters)tuningParameters forRangeMode:(ASLayoutRangeMode)rangeMode rangeType:(ASLayoutRangeType)rangeType
{ {
[_rangeController setTuningParameters:tuningParameters forRangeMode:rangeMode rangeType:rangeType]; [_collectionNode setTuningParameters:tuningParameters forRangeMode:rangeMode rangeType:rangeType];
} }
- (ASRangeTuningParameters)tuningParametersForRangeMode:(ASLayoutRangeMode)rangeMode rangeType:(ASLayoutRangeType)rangeType - (ASRangeTuningParameters)tuningParametersForRangeMode:(ASLayoutRangeMode)rangeMode rangeType:(ASLayoutRangeType)rangeType
{ {
return [_rangeController tuningParametersForRangeMode:rangeMode rangeType:rangeType]; return [_collectionNode tuningParametersForRangeMode:rangeMode rangeType:rangeType];
} }
- (CGSize)calculatedSizeForNodeAtIndexPath:(NSIndexPath *)indexPath - (CGSize)calculatedSizeForNodeAtIndexPath:(NSIndexPath *)indexPath
@ -517,21 +517,18 @@ static NSString * const kCellReuseIdentifier = @"_ASCollectionViewCell";
- (void)insertSections:(NSIndexSet *)sections - (void)insertSections:(NSIndexSet *)sections
{ {
ASDisplayNodeAssertMainThread(); ASDisplayNodeAssertMainThread();
if (sections.count == 0) { return; }
[_dataController insertSections:sections withAnimationOptions:kASCollectionViewAnimationNone]; [_dataController insertSections:sections withAnimationOptions:kASCollectionViewAnimationNone];
} }
- (void)deleteSections:(NSIndexSet *)sections - (void)deleteSections:(NSIndexSet *)sections
{ {
ASDisplayNodeAssertMainThread(); ASDisplayNodeAssertMainThread();
if (sections.count == 0) { return; }
[_dataController deleteSections:sections withAnimationOptions:kASCollectionViewAnimationNone]; [_dataController deleteSections:sections withAnimationOptions:kASCollectionViewAnimationNone];
} }
- (void)reloadSections:(NSIndexSet *)sections - (void)reloadSections:(NSIndexSet *)sections
{ {
ASDisplayNodeAssertMainThread(); ASDisplayNodeAssertMainThread();
if (sections.count == 0) { return; }
[_dataController reloadSections:sections withAnimationOptions:kASCollectionViewAnimationNone]; [_dataController reloadSections:sections withAnimationOptions:kASCollectionViewAnimationNone];
} }
@ -544,21 +541,18 @@ static NSString * const kCellReuseIdentifier = @"_ASCollectionViewCell";
- (void)insertItemsAtIndexPaths:(NSArray *)indexPaths - (void)insertItemsAtIndexPaths:(NSArray *)indexPaths
{ {
ASDisplayNodeAssertMainThread(); ASDisplayNodeAssertMainThread();
if (indexPaths.count == 0) { return; }
[_dataController insertRowsAtIndexPaths:indexPaths withAnimationOptions:kASCollectionViewAnimationNone]; [_dataController insertRowsAtIndexPaths:indexPaths withAnimationOptions:kASCollectionViewAnimationNone];
} }
- (void)deleteItemsAtIndexPaths:(NSArray *)indexPaths - (void)deleteItemsAtIndexPaths:(NSArray *)indexPaths
{ {
ASDisplayNodeAssertMainThread(); ASDisplayNodeAssertMainThread();
if (indexPaths.count == 0) { return; }
[_dataController deleteRowsAtIndexPaths:indexPaths withAnimationOptions:kASCollectionViewAnimationNone]; [_dataController deleteRowsAtIndexPaths:indexPaths withAnimationOptions:kASCollectionViewAnimationNone];
} }
- (void)reloadItemsAtIndexPaths:(NSArray *)indexPaths - (void)reloadItemsAtIndexPaths:(NSArray *)indexPaths
{ {
ASDisplayNodeAssertMainThread(); ASDisplayNodeAssertMainThread();
if (indexPaths.count == 0) { return; }
[_dataController reloadRowsAtIndexPaths:indexPaths withAnimationOptions:kASCollectionViewAnimationNone]; [_dataController reloadRowsAtIndexPaths:indexPaths withAnimationOptions:kASCollectionViewAnimationNone];
} }

View File

@ -465,13 +465,6 @@ NS_ASSUME_NONNULL_BEGIN
*/ */
- (NSString *)descriptionForRecursiveDescription; - (NSString *)descriptionForRecursiveDescription;
/**
* @abstract Called when the node's ASTraitCollection changes
*
* @discussion Subclasses can override this method to react to a trait collection change.
*/
- (void)asyncTraitCollectionDidChange;
@end @end
#define ASDisplayNodeAssertThreadAffinity(viewNode) ASDisplayNodeAssert(!viewNode || ASDisplayNodeThreadIsMain() || !(viewNode).nodeLoaded, @"Incorrect display node thread affinity - this method should not be called off the main thread after the ASDisplayNode's view or layer have been created") #define ASDisplayNodeAssertThreadAffinity(viewNode) ASDisplayNodeAssert(!viewNode || ASDisplayNodeThreadIsMain() || !(viewNode).nodeLoaded, @"Incorrect display node thread affinity - this method should not be called off the main thread after the ASDisplayNode's view or layer have been created")

View File

@ -1100,14 +1100,7 @@ static ASDisplayNodeMethodOverrides GetASDisplayNodeMethodOverrides(Class c)
// measureWithSizeRange: on subnodes to assert. // measureWithSizeRange: on subnodes to assert.
return; return;
} }
// Handle placeholder layer creation in case the size of the node changed after the initial placeholder layer
// was created
if ([self _shouldHavePlaceholderLayer]) {
[self _setupPlaceholderLayerIfNeeded];
}
_placeholderLayer.frame = bounds; _placeholderLayer.frame = bounds;
[self layout]; [self layout];
[self layoutDidFinish]; [self layoutDidFinish];
} }
@ -2762,12 +2755,7 @@ static const char *ASDisplayNodeDrawingPriorityKey = "ASDrawingPriority";
- (void)setEnvironmentState:(ASEnvironmentState)environmentState - (void)setEnvironmentState:(ASEnvironmentState)environmentState
{ {
ASEnvironmentTraitCollection oldTraitCollection = _environmentState.environmentTraitCollection;
_environmentState = environmentState; _environmentState = environmentState;
if (ASEnvironmentTraitCollectionIsEqualToASEnvironmentTraitCollection(oldTraitCollection, _environmentState.environmentTraitCollection) == NO) {
[self asyncTraitCollectionDidChange];
}
} }
- (ASDisplayNode *)parent - (ASDisplayNode *)parent
@ -2797,10 +2785,7 @@ static const char *ASDisplayNodeDrawingPriorityKey = "ASDrawingPriority";
- (void)setEnvironmentTraitCollection:(ASEnvironmentTraitCollection)environmentTraitCollection - (void)setEnvironmentTraitCollection:(ASEnvironmentTraitCollection)environmentTraitCollection
{ {
if (ASEnvironmentTraitCollectionIsEqualToASEnvironmentTraitCollection(environmentTraitCollection, _environmentState.environmentTraitCollection) == NO) { _environmentState.environmentTraitCollection = environmentTraitCollection;
_environmentState.environmentTraitCollection = environmentTraitCollection;
[self asyncTraitCollectionDidChange];
}
} }
ASEnvironmentLayoutOptionsForwarding ASEnvironmentLayoutOptionsForwarding
@ -2812,11 +2797,6 @@ ASEnvironmentLayoutExtensibilityForwarding
return [ASTraitCollection traitCollectionWithASEnvironmentTraitCollection:self.environmentTraitCollection]; return [ASTraitCollection traitCollectionWithASEnvironmentTraitCollection:self.environmentTraitCollection];
} }
- (void)asyncTraitCollectionDidChange
{
}
#if TARGET_OS_TV #if TARGET_OS_TV
#pragma mark - UIFocusEnvironment Protocol (tvOS) #pragma mark - UIFocusEnvironment Protocol (tvOS)

View File

@ -22,6 +22,8 @@
* This method replaces -collectionView:numberOfItemsInSection: * This method replaces -collectionView:numberOfItemsInSection:
* *
* @param pagerNode The sender. * @param pagerNode The sender.
*
*
* @returns The total number of pages that can display in the pagerNode. * @returns The total number of pages that can display in the pagerNode.
*/ */
- (NSInteger)numberOfPagesInPagerNode:(ASPagerNode *)pagerNode; - (NSInteger)numberOfPagesInPagerNode:(ASPagerNode *)pagerNode;
@ -32,7 +34,9 @@
* This method replaces -collectionView:nodeForItemAtIndexPath: * This method replaces -collectionView:nodeForItemAtIndexPath:
* *
* @param pagerNode The sender. * @param pagerNode The sender.
* @param index The index of the requested node. *
* @param index The index of the requested node.
*
* @returns a node for display at this index. This will be called on the main thread and should * @returns a node for display at this index. This will be called on the main thread and should
* not implement reuse (it will be called once per row). Unlike UICollectionView's version, * not implement reuse (it will be called once per row). Unlike UICollectionView's version,
* this method is not called when the row is about to display. * this method is not called when the row is about to display.
@ -44,7 +48,9 @@
* This method takes precedence over pagerNode:nodeAtIndex: if implemented. * This method takes precedence over pagerNode:nodeAtIndex: if implemented.
* *
* @param pagerNode The sender. * @param pagerNode The sender.
* @param index The index of the requested node. *
* @param index The index of the requested node.
*
* @returns a block that creates the node for display at this index. * @returns a block that creates the node for display at this index.
* Must be thread-safe (can be called on the main thread or a background * Must be thread-safe (can be called on the main thread or a background
* queue) and should not implement reuse (it will be called once per row). * queue) and should not implement reuse (it will be called once per row).
@ -55,7 +61,9 @@
* Provides the constrained size range for measuring the node at the index path. * Provides the constrained size range for measuring the node at the index path.
* *
* @param pagerNode The sender. * @param pagerNode The sender.
*
* @param indexPath The index path of the node. * @param indexPath The index path of the node.
*
* @returns A constrained size range for layout the node at this index path. * @returns A constrained size range for layout the node at this index path.
*/ */
- (ASSizeRange)pagerNode:(ASPagerNode *)pagerNode constrainedSizeForNodeAtIndexPath:(NSIndexPath *)indexPath; - (ASSizeRange)pagerNode:(ASPagerNode *)pagerNode constrainedSizeForNodeAtIndexPath:(NSIndexPath *)indexPath;
@ -68,46 +76,27 @@
@interface ASPagerNode : ASCollectionNode @interface ASPagerNode : ASCollectionNode
/** /// Configures a default horizontal, paging flow layout with 0 inter-item spacing.
* Configures a default horizontal, paging flow layout with 0 inter-item spacing.
*/
- (instancetype)init; - (instancetype)init;
/** /// Initializer with custom-configured flow layout properties.
* Initializer with custom-configured flow layout properties.
*/
- (instancetype)initWithCollectionViewLayout:(ASPagerFlowLayout *)flowLayout; - (instancetype)initWithCollectionViewLayout:(ASPagerFlowLayout *)flowLayout;
/** /// Data Source is required, and uses a different protocol from ASCollectionNode.
* Data Source is required, and uses a different protocol from ASCollectionNode.
*/
- (void)setDataSource:(id <ASPagerDataSource>)dataSource; - (void)setDataSource:(id <ASPagerDataSource>)dataSource;
- (id <ASPagerDataSource>)dataSource; - (id <ASPagerDataSource>)dataSource;
/** // Delegate is optional, and uses the same protocol as ASCollectionNode.
* Delegate is optional, and uses the same protocol as ASCollectionNode. // This includes UIScrollViewDelegate as well as most methods from UICollectionViewDelegate, like willDisplay...
* This includes UIScrollViewDelegate as well as most methods from UICollectionViewDelegate, like willDisplay...
*/
@property (nonatomic, weak) id <ASPagerDelegate> delegate; @property (nonatomic, weak) id <ASPagerDelegate> delegate;
/** /// The underlying ASCollectionView object.
* The underlying ASCollectionView object.
*/
@property (nonatomic, readonly) ASCollectionView *view; @property (nonatomic, readonly) ASCollectionView *view;
/** /// Returns the current page index
* Returns the current page index
*/
@property (nonatomic, assign, readonly) NSInteger currentPageIndex; @property (nonatomic, assign, readonly) NSInteger currentPageIndex;
/** /// Scroll the contents of the receiver to ensure that the page is visible
* Scroll the contents of the receiver to ensure that the page is visible
*/
- (void)scrollToPageAtIndex:(NSInteger)index animated:(BOOL)animated; - (void)scrollToPageAtIndex:(NSInteger)index animated:(BOOL)animated;
/**
* Returns the node for the passed page index
*/
- (ASCellNode *)nodeForPageAtIndex:(NSInteger)index;
@end @end

View File

@ -98,11 +98,6 @@
[self.view scrollToItemAtIndexPath:indexPath atScrollPosition:UICollectionViewScrollPositionLeft animated:animated]; [self.view scrollToItemAtIndexPath:indexPath atScrollPosition:UICollectionViewScrollPositionLeft animated:animated];
} }
- (ASCellNode *)nodeForPageAtIndex:(NSInteger)index
{
return [self.view nodeForItemAtIndexPath:[NSIndexPath indexPathForItem:index inSection:0]];
}
#pragma mark - ASCollectionViewDataSource #pragma mark - ASCollectionViewDataSource
- (ASCellNodeBlock)collectionView:(ASCollectionView *)collectionView nodeBlockForItemAtIndexPath:(NSIndexPath *)indexPath - (ASCellNodeBlock)collectionView:(ASCollectionView *)collectionView nodeBlockForItemAtIndexPath:(NSIndexPath *)indexPath

View File

@ -433,18 +433,6 @@ NS_ASSUME_NONNULL_BEGIN
*/ */
- (BOOL)shouldBatchFetchForTableView:(ASTableView *)tableView; - (BOOL)shouldBatchFetchForTableView:(ASTableView *)tableView;
/**
* Provides the constrained size range for measuring the row at the index path.
* Note: the widths in the returned size range are ignored!
*
* @param tableView The sender.
*
* @param indexPath The index path of the node.
*
* @returns A constrained size range for layout the node at this index path.
*/
- (ASSizeRange)tableView:(ASTableView *)tableView constrainedSizeForRowAtIndexPath:(NSIndexPath *)indexPath;
/** /**
* Informs the delegate that the table view did remove the node which was previously * Informs the delegate that the table view did remove the node which was previously
* at the given index path from the view hierarchy. * at the given index path from the view hierarchy.

View File

@ -28,7 +28,6 @@
#import <CoreFoundation/CoreFoundation.h> #import <CoreFoundation/CoreFoundation.h>
static const ASSizeRange kInvalidSizeRange = {CGSizeZero, CGSizeZero};
static NSString * const kCellReuseIdentifier = @"_ASTableViewCell"; static NSString * const kCellReuseIdentifier = @"_ASTableViewCell";
//#define LOG(...) NSLog(__VA_ARGS__) //#define LOG(...) NSLog(__VA_ARGS__)
@ -145,7 +144,6 @@ static NSString * const kCellReuseIdentifier = @"_ASTableViewCell";
unsigned int asyncDelegateScrollViewWillEndDraggingWithVelocityTargetContentOffset:1; unsigned int asyncDelegateScrollViewWillEndDraggingWithVelocityTargetContentOffset:1;
unsigned int asyncDelegateTableViewWillBeginBatchFetchWithContext:1; unsigned int asyncDelegateTableViewWillBeginBatchFetchWithContext:1;
unsigned int asyncDelegateShouldBatchFetchForTableView:1; unsigned int asyncDelegateShouldBatchFetchForTableView:1;
unsigned int asyncDelegateTableViewConstrainedSizeForRowAtIndexPath:1;
} _asyncDelegateFlags; } _asyncDelegateFlags;
struct { struct {
@ -166,7 +164,6 @@ static NSString * const kCellReuseIdentifier = @"_ASTableViewCell";
// Always set, whether ASCollectionView is created directly or via ASCollectionNode. // Always set, whether ASCollectionView is created directly or via ASCollectionNode.
@property (nonatomic, weak) ASTableNode *tableNode; @property (nonatomic, weak) ASTableNode *tableNode;
@property (nonatomic) BOOL test_enableSuperUpdateCallLogging;
@end @end
@implementation ASTableView @implementation ASTableView
@ -338,8 +335,6 @@ static NSString * const kCellReuseIdentifier = @"_ASTableViewCell";
_asyncDelegateFlags.asyncDelegateShouldBatchFetchForTableView = [_asyncDelegate respondsToSelector:@selector(shouldBatchFetchForTableView:)]; _asyncDelegateFlags.asyncDelegateShouldBatchFetchForTableView = [_asyncDelegate respondsToSelector:@selector(shouldBatchFetchForTableView:)];
_asyncDelegateFlags.asyncDelegateScrollViewWillBeginDragging = [_asyncDelegate respondsToSelector:@selector(scrollViewWillBeginDragging:)]; _asyncDelegateFlags.asyncDelegateScrollViewWillBeginDragging = [_asyncDelegate respondsToSelector:@selector(scrollViewWillBeginDragging:)];
_asyncDelegateFlags.asyncDelegateScrollViewDidEndDragging = [_asyncDelegate respondsToSelector:@selector(scrollViewDidEndDragging:willDecelerate:)]; _asyncDelegateFlags.asyncDelegateScrollViewDidEndDragging = [_asyncDelegate respondsToSelector:@selector(scrollViewDidEndDragging:willDecelerate:)];
_asyncDelegateFlags.asyncDelegateTableViewConstrainedSizeForRowAtIndexPath = [_asyncDelegate respondsToSelector:@selector(tableView:constrainedSizeForRowAtIndexPath:)];
} }
super.delegate = (id<UITableViewDelegate>)_proxyDelegate; super.delegate = (id<UITableViewDelegate>)_proxyDelegate;
@ -479,21 +474,18 @@ static NSString * const kCellReuseIdentifier = @"_ASTableViewCell";
- (void)insertSections:(NSIndexSet *)sections withRowAnimation:(UITableViewRowAnimation)animation - (void)insertSections:(NSIndexSet *)sections withRowAnimation:(UITableViewRowAnimation)animation
{ {
ASDisplayNodeAssertMainThread(); ASDisplayNodeAssertMainThread();
if (sections.count == 0) { return; }
[_dataController insertSections:sections withAnimationOptions:animation]; [_dataController insertSections:sections withAnimationOptions:animation];
} }
- (void)deleteSections:(NSIndexSet *)sections withRowAnimation:(UITableViewRowAnimation)animation - (void)deleteSections:(NSIndexSet *)sections withRowAnimation:(UITableViewRowAnimation)animation
{ {
ASDisplayNodeAssertMainThread(); ASDisplayNodeAssertMainThread();
if (sections.count == 0) { return; }
[_dataController deleteSections:sections withAnimationOptions:animation]; [_dataController deleteSections:sections withAnimationOptions:animation];
} }
- (void)reloadSections:(NSIndexSet *)sections withRowAnimation:(UITableViewRowAnimation)animation - (void)reloadSections:(NSIndexSet *)sections withRowAnimation:(UITableViewRowAnimation)animation
{ {
ASDisplayNodeAssertMainThread(); ASDisplayNodeAssertMainThread();
if (sections.count == 0) { return; }
[_dataController reloadSections:sections withAnimationOptions:animation]; [_dataController reloadSections:sections withAnimationOptions:animation];
} }
@ -506,21 +498,18 @@ static NSString * const kCellReuseIdentifier = @"_ASTableViewCell";
- (void)insertRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation - (void)insertRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation
{ {
ASDisplayNodeAssertMainThread(); ASDisplayNodeAssertMainThread();
if (indexPaths.count == 0) { return; }
[_dataController insertRowsAtIndexPaths:indexPaths withAnimationOptions:animation]; [_dataController insertRowsAtIndexPaths:indexPaths withAnimationOptions:animation];
} }
- (void)deleteRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation - (void)deleteRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation
{ {
ASDisplayNodeAssertMainThread(); ASDisplayNodeAssertMainThread();
if (indexPaths.count == 0) { return; }
[_dataController deleteRowsAtIndexPaths:indexPaths withAnimationOptions:animation]; [_dataController deleteRowsAtIndexPaths:indexPaths withAnimationOptions:animation];
} }
- (void)reloadRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation - (void)reloadRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation
{ {
ASDisplayNodeAssertMainThread(); ASDisplayNodeAssertMainThread();
if (indexPaths.count == 0) { return; }
[_dataController reloadRowsAtIndexPaths:indexPaths withAnimationOptions:animation]; [_dataController reloadRowsAtIndexPaths:indexPaths withAnimationOptions:animation];
} }
@ -1004,9 +993,6 @@ static NSString * const kCellReuseIdentifier = @"_ASTableViewCell";
BOOL preventAnimation = animationOptions == UITableViewRowAnimationNone; BOOL preventAnimation = animationOptions == UITableViewRowAnimationNone;
ASPerformBlockWithoutAnimation(preventAnimation, ^{ ASPerformBlockWithoutAnimation(preventAnimation, ^{
if (self.test_enableSuperUpdateCallLogging) {
NSLog(@"-[super insertRowsAtIndexPaths]: %@", indexPaths);
}
[super insertRowsAtIndexPaths:indexPaths withRowAnimation:(UITableViewRowAnimation)animationOptions]; [super insertRowsAtIndexPaths:indexPaths withRowAnimation:(UITableViewRowAnimation)animationOptions];
[self _scheduleCheckForBatchFetchingForNumberOfChanges:indexPaths.count]; [self _scheduleCheckForBatchFetchingForNumberOfChanges:indexPaths.count];
}); });
@ -1027,9 +1013,6 @@ static NSString * const kCellReuseIdentifier = @"_ASTableViewCell";
BOOL preventAnimation = animationOptions == UITableViewRowAnimationNone; BOOL preventAnimation = animationOptions == UITableViewRowAnimationNone;
ASPerformBlockWithoutAnimation(preventAnimation, ^{ ASPerformBlockWithoutAnimation(preventAnimation, ^{
if (self.test_enableSuperUpdateCallLogging) {
NSLog(@"-[super deleteRowsAtIndexPaths]: %@", indexPaths);
}
[super deleteRowsAtIndexPaths:indexPaths withRowAnimation:(UITableViewRowAnimation)animationOptions]; [super deleteRowsAtIndexPaths:indexPaths withRowAnimation:(UITableViewRowAnimation)animationOptions];
[self _scheduleCheckForBatchFetchingForNumberOfChanges:indexPaths.count]; [self _scheduleCheckForBatchFetchingForNumberOfChanges:indexPaths.count];
}); });
@ -1051,9 +1034,6 @@ static NSString * const kCellReuseIdentifier = @"_ASTableViewCell";
BOOL preventAnimation = animationOptions == UITableViewRowAnimationNone; BOOL preventAnimation = animationOptions == UITableViewRowAnimationNone;
ASPerformBlockWithoutAnimation(preventAnimation, ^{ ASPerformBlockWithoutAnimation(preventAnimation, ^{
if (self.test_enableSuperUpdateCallLogging) {
NSLog(@"-[super insertSections]: %@", indexSet);
}
[super insertSections:indexSet withRowAnimation:(UITableViewRowAnimation)animationOptions]; [super insertSections:indexSet withRowAnimation:(UITableViewRowAnimation)animationOptions];
[self _scheduleCheckForBatchFetchingForNumberOfChanges:indexSet.count]; [self _scheduleCheckForBatchFetchingForNumberOfChanges:indexSet.count];
}); });
@ -1070,9 +1050,6 @@ static NSString * const kCellReuseIdentifier = @"_ASTableViewCell";
BOOL preventAnimation = animationOptions == UITableViewRowAnimationNone; BOOL preventAnimation = animationOptions == UITableViewRowAnimationNone;
ASPerformBlockWithoutAnimation(preventAnimation, ^{ ASPerformBlockWithoutAnimation(preventAnimation, ^{
if (self.test_enableSuperUpdateCallLogging) {
NSLog(@"-[super deleteSections]: %@", indexSet);
}
[super deleteSections:indexSet withRowAnimation:(UITableViewRowAnimation)animationOptions]; [super deleteSections:indexSet withRowAnimation:(UITableViewRowAnimation)animationOptions];
[self _scheduleCheckForBatchFetchingForNumberOfChanges:indexSet.count]; [self _scheduleCheckForBatchFetchingForNumberOfChanges:indexSet.count];
}); });
@ -1111,17 +1088,8 @@ static NSString * const kCellReuseIdentifier = @"_ASTableViewCell";
- (ASSizeRange)dataController:(ASDataController *)dataController constrainedSizeForNodeAtIndexPath:(NSIndexPath *)indexPath - (ASSizeRange)dataController:(ASDataController *)dataController constrainedSizeForNodeAtIndexPath:(NSIndexPath *)indexPath
{ {
ASSizeRange constrainedSize = kInvalidSizeRange; return ASSizeRangeMake(CGSizeMake(_nodesConstrainedWidth, 0),
if (_asyncDelegateFlags.asyncDelegateTableViewConstrainedSizeForRowAtIndexPath) { CGSizeMake(_nodesConstrainedWidth, FLT_MAX));
ASSizeRange delegateConstrainedSize = [_asyncDelegate tableView:self constrainedSizeForRowAtIndexPath:indexPath];
// ignore widths in the returned size range (for TableView)
constrainedSize = ASSizeRangeMake(CGSizeMake(_nodesConstrainedWidth, delegateConstrainedSize.min.height),
CGSizeMake(_nodesConstrainedWidth, delegateConstrainedSize.max.height));
} else {
constrainedSize = ASSizeRangeMake(CGSizeMake(_nodesConstrainedWidth, 0),
CGSizeMake(_nodesConstrainedWidth, FLT_MAX));
}
return constrainedSize;
} }
- (NSUInteger)dataController:(ASDataController *)dataController rowsInSection:(NSUInteger)section - (NSUInteger)dataController:(ASDataController *)dataController rowsInSection:(NSUInteger)section

View File

@ -34,7 +34,4 @@
*/ */
- (instancetype)_initWithFrame:(CGRect)frame style:(UITableViewStyle)style dataControllerClass:(Class)dataControllerClass ownedByNode:(BOOL)ownedByNode; - (instancetype)_initWithFrame:(CGRect)frame style:(UITableViewStyle)style dataControllerClass:(Class)dataControllerClass ownedByNode:(BOOL)ownedByNode;
/// Set YES and we'll log every time we call [super insertRows…] etc
@property (nonatomic) BOOL test_enableSuperUpdateCallLogging;
@end @end

View File

@ -366,36 +366,32 @@ static NSArray *DefaultLinkAttributeNames = @[ NSLinkAttributeName ];
- (void)setAttributedText:(NSAttributedString *)attributedText - (void)setAttributedText:(NSAttributedString *)attributedText
{ {
std::lock_guard<std::recursive_mutex> l(_textLock);
if (attributedText == nil) { if (attributedText == nil) {
attributedText = [[NSAttributedString alloc] initWithString:@"" attributes:nil]; attributedText = [[NSAttributedString alloc] initWithString:@"" attributes:nil];
} }
// Don't hold textLock for too long.
{
std::lock_guard<std::recursive_mutex> l(_textLock);
if (ASObjectIsEqual(attributedText, _attributedText)) {
return;
}
_attributedText = ASCleanseAttributedStringOfCoreTextAttributes(attributedText); if (ASObjectIsEqual(attributedText, _attributedText)) {
return;
// Sync the truncation string with attributes from the updated _attributedString
// Without this, the size calculation of the text with truncation applied will
// not take into account the attributes of attributedText in the last line
[self _updateComposedTruncationText];
// We need an entirely new renderer
[self _invalidateRenderer];
} }
NSUInteger length = attributedText.length; _attributedText = ASCleanseAttributedStringOfCoreTextAttributes(attributedText);
if (length > 0) {
if (_attributedText.length > 0) {
CGFloat screenScale = ASScreenScale(); CGFloat screenScale = ASScreenScale();
self.ascender = round([[attributedText attribute:NSFontAttributeName atIndex:0 effectiveRange:NULL] ascender] * screenScale)/screenScale; self.ascender = round([[_attributedText attribute:NSFontAttributeName atIndex:0 effectiveRange:NULL] ascender] * screenScale)/screenScale;
self.descender = round([[attributedText attribute:NSFontAttributeName atIndex:length - 1 effectiveRange:NULL] descender] * screenScale)/screenScale; self.descender = round([[_attributedText attribute:NSFontAttributeName atIndex:_attributedText.length - 1 effectiveRange:NULL] descender] * screenScale)/screenScale;
} }
// Sync the truncation string with attributes from the updated _attributedString
// Without this, the size calculation of the text with truncation applied will
// not take into account the attributes of attributedText in the last line
[self _updateComposedTruncationText];
// We need an entirely new renderer
[self _invalidateRenderer];
// Tell the display node superclasses that the cached layout is incorrect now // Tell the display node superclasses that the cached layout is incorrect now
[self invalidateCalculatedLayout]; [self invalidateCalculatedLayout];
@ -403,8 +399,8 @@ static NSArray *DefaultLinkAttributeNames = @[ NSLinkAttributeName ];
// Accessiblity // Accessiblity
self.accessibilityLabel = attributedText.string; self.accessibilityLabel = _attributedText.string;
self.isAccessibilityElement = (length != 0); // We're an accessibility element by default if there is a string. self.isAccessibilityElement = (_attributedText.length != 0); // We're an accessibility element by default if there is a string.
} }
#pragma mark - Text Layout #pragma mark - Text Layout

View File

@ -164,10 +164,6 @@ static NSString * const kStatus = @"status";
- (void)addPlayerItemObservers:(AVPlayerItem *)playerItem - (void)addPlayerItemObservers:(AVPlayerItem *)playerItem
{ {
if (playerItem == nil) {
return;
}
[playerItem addObserver:self forKeyPath:kStatus options:NSKeyValueObservingOptionInitial | NSKeyValueObservingOptionNew context:ASVideoNodeContext]; [playerItem addObserver:self forKeyPath:kStatus options:NSKeyValueObservingOptionInitial | NSKeyValueObservingOptionNew context:ASVideoNodeContext];
[playerItem addObserver:self forKeyPath:kPlaybackLikelyToKeepUpKey options:NSKeyValueObservingOptionNew context:ASVideoNodeContext]; [playerItem addObserver:self forKeyPath:kPlaybackLikelyToKeepUpKey options:NSKeyValueObservingOptionNew context:ASVideoNodeContext];
[playerItem addObserver:self forKeyPath:kplaybackBufferEmpty options:NSKeyValueObservingOptionNew context:ASVideoNodeContext]; [playerItem addObserver:self forKeyPath:kplaybackBufferEmpty options:NSKeyValueObservingOptionNew context:ASVideoNodeContext];
@ -645,9 +641,7 @@ static NSString * const kStatus = @"status";
_currentPlayerItem = currentItem; _currentPlayerItem = currentItem;
if (currentItem != nil) { [self addPlayerItemObservers:currentItem];
[self addPlayerItemObservers:currentItem];
}
} }
- (ASDisplayNode *)playerNode - (ASDisplayNode *)playerNode

View File

@ -49,7 +49,6 @@ NS_ASSUME_NONNULL_BEGIN
@property (nonatomic, assign, readwrite) BOOL muted; @property (nonatomic, assign, readwrite) BOOL muted;
@property (nonatomic, assign, readonly) ASVideoNodePlayerState playerState; @property (nonatomic, assign, readonly) ASVideoNodePlayerState playerState;
@property (nonatomic, assign, readwrite) BOOL shouldAggressivelyRecoverFromStall; @property (nonatomic, assign, readwrite) BOOL shouldAggressivelyRecoverFromStall;
@property (nullable, atomic, strong, readwrite) NSURL *placeholderImageURL;
//! Defaults to 100 //! Defaults to 100
@property (nonatomic, assign) int32_t periodicTimeObserverTimescale; @property (nonatomic, assign) int32_t periodicTimeObserverTimescale;

View File

@ -76,9 +76,6 @@ static void *ASVideoPlayerNodeContext = &ASVideoPlayerNodeContext;
@end @end
@implementation ASVideoPlayerNode @implementation ASVideoPlayerNode
@dynamic placeholderImageURL;
- (instancetype)init - (instancetype)init
{ {
if (!(self = [super init])) { if (!(self = [super init])) {
@ -774,16 +771,6 @@ static void *ASVideoPlayerNodeContext = &ASVideoPlayerNodeContext;
return _videoNode.shouldAggressivelyRecoverFromStall; return _videoNode.shouldAggressivelyRecoverFromStall;
} }
- (void) setPlaceholderImageURL:(NSURL *)placeholderImageURL
{
_videoNode.URL = placeholderImageURL;
}
- (NSURL*) placeholderImageURL
{
return _videoNode.URL;
}
- (void)setShouldAggressivelyRecoverFromStall:(BOOL)shouldAggressivelyRecoverFromStall - (void)setShouldAggressivelyRecoverFromStall:(BOOL)shouldAggressivelyRecoverFromStall
{ {
if (_shouldAggressivelyRecoverFromStall == shouldAggressivelyRecoverFromStall) { if (_shouldAggressivelyRecoverFromStall == shouldAggressivelyRecoverFromStall) {

View File

@ -14,7 +14,6 @@
#import "ASInternalHelpers.h" #import "ASInternalHelpers.h"
#import "_ASHierarchyChangeSet.h" #import "_ASHierarchyChangeSet.h"
#import "ASAssert.h" #import "ASAssert.h"
#import "NSIndexSet+ASHelpers.h"
#import "ASDataController+Subclasses.h" #import "ASDataController+Subclasses.h"
@ -48,9 +47,6 @@
[super beginUpdates]; [super beginUpdates];
NSAssert([_changeSet itemChangesOfType:_ASHierarchyChangeTypeReload].count == 0, @"Expected reload item changes to have been converted into insert/deletes.");
NSAssert([_changeSet sectionChangesOfType:_ASHierarchyChangeTypeReload].count == 0, @"Expected reload section changes to have been converted into insert/deletes.");
for (_ASHierarchyItemChange *change in [_changeSet itemChangesOfType:_ASHierarchyChangeTypeDelete]) { for (_ASHierarchyItemChange *change in [_changeSet itemChangesOfType:_ASHierarchyChangeTypeDelete]) {
[super deleteRowsAtIndexPaths:change.indexPaths withAnimationOptions:change.animationOptions]; [super deleteRowsAtIndexPaths:change.indexPaths withAnimationOptions:change.animationOptions];
} }
@ -58,7 +54,17 @@
for (_ASHierarchySectionChange *change in [_changeSet sectionChangesOfType:_ASHierarchyChangeTypeDelete]) { for (_ASHierarchySectionChange *change in [_changeSet sectionChangesOfType:_ASHierarchyChangeTypeDelete]) {
[super deleteSections:change.indexSet withAnimationOptions:change.animationOptions]; [super deleteSections:change.indexSet withAnimationOptions:change.animationOptions];
} }
// TODO: Shouldn't reloads be processed before deletes, since deletes affect
// the index space and reloads don't?
for (_ASHierarchySectionChange *change in [_changeSet sectionChangesOfType:_ASHierarchyChangeTypeReload]) {
[super reloadSections:change.indexSet withAnimationOptions:change.animationOptions];
}
for (_ASHierarchyItemChange *change in [_changeSet itemChangesOfType:_ASHierarchyChangeTypeReload]) {
[super reloadRowsAtIndexPaths:change.indexPaths withAnimationOptions:change.animationOptions];
}
for (_ASHierarchySectionChange *change in [_changeSet sectionChangesOfType:_ASHierarchyChangeTypeInsert]) { for (_ASHierarchySectionChange *change in [_changeSet sectionChangesOfType:_ASHierarchyChangeTypeInsert]) {
[super insertSections:change.indexSet withAnimationOptions:change.animationOptions]; [super insertSections:change.indexSet withAnimationOptions:change.animationOptions];
} }
@ -109,10 +115,7 @@
if ([self batchUpdating]) { if ([self batchUpdating]) {
[_changeSet reloadSections:sections animationOptions:animationOptions]; [_changeSet reloadSections:sections animationOptions:animationOptions];
} else { } else {
[self beginUpdates]; [super reloadSections:sections withAnimationOptions:animationOptions];
[super deleteSections:sections withAnimationOptions:animationOptions];
[super insertSections:sections withAnimationOptions:animationOptions];
[self endUpdates];
} }
} }
@ -155,10 +158,7 @@
if ([self batchUpdating]) { if ([self batchUpdating]) {
[_changeSet reloadItems:indexPaths animationOptions:animationOptions]; [_changeSet reloadItems:indexPaths animationOptions:animationOptions];
} else { } else {
[self beginUpdates]; [super reloadRowsAtIndexPaths:indexPaths withAnimationOptions:animationOptions];
[super deleteRowsAtIndexPaths:indexPaths withAnimationOptions:animationOptions];
[super insertRowsAtIndexPaths:indexPaths withAnimationOptions:animationOptions];
[self endUpdates];
} }
} }

View File

@ -115,6 +115,30 @@
} }
} }
- (void)prepareForReloadSections:(NSIndexSet *)sections
{
for (NSString *kind in [self supplementaryKinds]) {
NSMutableArray<ASIndexedNodeContext *> *contexts = [NSMutableArray array];
[self _populateSupplementaryNodesOfKind:kind withSections:sections mutableContexts:contexts];
_pendingContexts[kind] = contexts;
}
}
- (void)willReloadSections:(NSIndexSet *)sections
{
NSArray *keys = _pendingContexts.allKeys;
for (NSString *kind in keys) {
NSMutableArray<ASIndexedNodeContext *> *contexts = _pendingContexts[kind];
NSArray *indexPaths = ASIndexPathsForMultidimensionalArrayAtIndexSet([self editingNodesOfKind:kind], sections);
[self deleteNodesOfKind:kind atIndexPaths:indexPaths completion:nil];
// reinsert the elements
[self batchLayoutNodesFromContexts:contexts ofKind:kind completion:^(NSArray<ASCellNode *> *nodes, NSArray<NSIndexPath *> *indexPaths) {
[self insertNodes:nodes ofKind:kind atIndexPaths:indexPaths completion:nil];
}];
[_pendingContexts removeObjectForKey:kind];
}
}
- (void)willMoveSection:(NSInteger)section toSection:(NSInteger)newSection - (void)willMoveSection:(NSInteger)section toSection:(NSInteger)newSection
{ {
for (NSString *kind in [self supplementaryKinds]) { for (NSString *kind in [self supplementaryKinds]) {
@ -163,6 +187,30 @@
} }
} }
- (void)prepareForReloadRowsAtIndexPaths:(NSArray<NSIndexPath *> *)indexPaths
{
for (NSString *kind in [self supplementaryKinds]) {
NSMutableArray<ASIndexedNodeContext *> *contexts = [NSMutableArray array];
[self _populateSupplementaryNodesOfKind:kind atIndexPaths:indexPaths mutableContexts:contexts];
_pendingContexts[kind] = contexts;
}
}
- (void)willReloadRowsAtIndexPaths:(NSArray<NSIndexPath *> *)indexPaths
{
NSArray *keys = _pendingContexts.allKeys;
for (NSString *kind in keys) {
NSMutableArray<ASIndexedNodeContext *> *contexts = _pendingContexts[kind];
[self deleteNodesOfKind:kind atIndexPaths:indexPaths completion:nil];
// reinsert the elements
[self batchLayoutNodesFromContexts:contexts ofKind:kind completion:^(NSArray<ASCellNode *> *nodes, NSArray<NSIndexPath *> *indexPaths) {
[self insertNodes:nodes ofKind:kind atIndexPaths:indexPaths completion:nil];
}];
[_pendingContexts removeObjectForKey:kind];
}
}
- (void)_populateSupplementaryNodesOfKind:(NSString *)kind withMutableContexts:(NSMutableArray<ASIndexedNodeContext *> *)contexts - (void)_populateSupplementaryNodesOfKind:(NSString *)kind withMutableContexts:(NSMutableArray<ASIndexedNodeContext *> *)contexts
{ {
id<ASEnvironment> environment = [self.environmentDelegate dataControllerEnvironment]; id<ASEnvironment> environment = [self.environmentDelegate dataControllerEnvironment];

View File

@ -128,6 +128,28 @@ typedef void (^ASDataControllerCompletionBlock)(NSArray<ASCellNode *> *nodes, NS
*/ */
- (void)willDeleteSections:(NSIndexSet *)sections; - (void)willDeleteSections:(NSIndexSet *)sections;
/**
* Notifies the subclass to perform any work needed before the given sections will be reloaded.
*
* @discussion This method will be performed before the data controller enters its editing queue, usually on the main
* thread. The data source is locked at this point and accessing it is safe. Use this method to set up any nodes or
* data stores before entering into editing the backing store on a background thread.
*
* @param sections Indices of sections to be reloaded
*/
- (void)prepareForReloadSections:(NSIndexSet *)sections;
/**
* Notifies the subclass that the data controller will reload the sections in the given index set
*
* @discussion This method will be performed on the data controller's editing background queue before the parent's
* concrete implementation. This is a great place to perform any additional transformations like supplementary views
* or header/footer nodes.
*
* @param sections Indices of sections to be reloaded
*/
- (void)willReloadSections:(NSIndexSet *)sections;
/** /**
* Notifies the subclass that the data controller will move a section to a new position * Notifies the subclass that the data controller will move a section to a new position
* *
@ -184,4 +206,26 @@ typedef void (^ASDataControllerCompletionBlock)(NSArray<ASCellNode *> *nodes, NS
*/ */
- (void)willDeleteRowsAtIndexPaths:(NSArray<NSIndexPath *> *)indexPaths; - (void)willDeleteRowsAtIndexPaths:(NSArray<NSIndexPath *> *)indexPaths;
/**
* Notifies the subclass to perform any work needed before the given rows will be reloaded.
*
* @discussion This method will be performed before the data controller enters its editing queue, usually on the main
* thread. The data source is locked at this point and accessing it is safe. Use this method to set up any nodes or
* data stores before entering into editing the backing store on a background thread.
*
* @param indexPaths Index paths for the rows to be reloaded.
*/
- (void)prepareForReloadRowsAtIndexPaths:(NSArray<NSIndexPath *> *)indexPaths;
/**
* Notifies the subclass that the data controller will reload the rows at the given index paths.
*
* @discussion This method will be performed on the data controller's editing background queue before the parent's
* concrete implementation. This is a great place to perform any additional transformations like supplementary views
* or header/footer nodes.
*
* @param indexPaths Index paths for the rows to be reloaded.
*/
- (void)willReloadRowsAtIndexPaths:(NSArray<NSIndexPath *> *)indexPaths;
@end @end

View File

@ -65,7 +65,6 @@ static void *kASSizingQueueContext = &kASSizingQueueContext;
if (!(self = [super init])) { if (!(self = [super init])) {
return nil; return nil;
} }
ASDisplayNodeAssert(![self isMemberOfClass:[ASDataController class]], @"ASDataController is an abstract class and should not be instantiated. Instantiate a subclass instead.");
_completedNodes = [NSMutableDictionary dictionary]; _completedNodes = [NSMutableDictionary dictionary];
_editingNodes = [NSMutableDictionary dictionary]; _editingNodes = [NSMutableDictionary dictionary];
@ -143,9 +142,8 @@ static void *kASSizingQueueContext = &kASSizingQueueContext;
*/ */
- (void)_layoutNode:(ASCellNode *)node withConstrainedSize:(ASSizeRange)constrainedSize - (void)_layoutNode:(ASCellNode *)node withConstrainedSize:(ASSizeRange)constrainedSize
{ {
CGRect frame = CGRectZero; CGSize size = [node measureWithSizeRange:constrainedSize].size;
frame.size = [node measureWithSizeRange:constrainedSize].size; node.frame = { .size = size };
node.frame = frame;
} }
/** /**
@ -663,7 +661,29 @@ static void *kASSizingQueueContext = &kASSizingQueueContext;
- (void)reloadSections:(NSIndexSet *)sections withAnimationOptions:(ASDataControllerAnimationOptions)animationOptions - (void)reloadSections:(NSIndexSet *)sections withAnimationOptions:(ASDataControllerAnimationOptions)animationOptions
{ {
ASDisplayNodeAssert(NO, @"ASDataController does not support %@. Call this on ASChangeSetDataController the reload will be broken into delete & insert.", NSStringFromSelector(_cmd)); [self performEditCommandWithBlock:^{
ASDisplayNodeAssertMainThread();
LOG(@"Edit Command - reloadSections: %@", sections);
[_editingTransactionQueue waitUntilAllOperationsAreFinished];
NSArray<ASIndexedNodeContext *> *contexts= [self _populateFromDataSourceWithSectionIndexSet:sections];
[self prepareForReloadSections:sections];
[_editingTransactionQueue addOperationWithBlock:^{
[self willReloadSections:sections];
NSArray *indexPaths = ASIndexPathsForMultidimensionalArrayAtIndexSet(_editingNodes[ASDataControllerRowNodeKind], sections);
LOG(@"Edit Transaction - reloadSections: updatedIndexPaths: %@, indexPaths: %@, _editingNodes: %@", updatedIndexPaths, indexPaths, ASIndexPathsForTwoDimensionalArray(_editingNodes[ASDataControllerRowNodeKind]));
[self _deleteNodesAtIndexPaths:indexPaths withAnimationOptions:animationOptions];
// reinsert the elements
[self _batchLayoutNodesFromContexts:contexts withAnimationOptions:animationOptions];
}];
}];
} }
- (void)moveSection:(NSInteger)section toSection:(NSInteger)newSection withAnimationOptions:(ASDataControllerAnimationOptions)animationOptions - (void)moveSection:(NSInteger)section toSection:(NSInteger)newSection withAnimationOptions:(ASDataControllerAnimationOptions)animationOptions
@ -726,6 +746,16 @@ static void *kASSizingQueueContext = &kASSizingQueueContext;
// Optional template hook for subclasses (See ASDataController+Subclasses.h) // Optional template hook for subclasses (See ASDataController+Subclasses.h)
} }
- (void)prepareForReloadSections:(NSIndexSet *)sections
{
// Optional template hook for subclasses (See ASDataController+Subclasses.h)
}
- (void)willReloadSections:(NSIndexSet *)sections
{
// Optional template hook for subclasses (See ASDataController+Subclasses.h)
}
- (void)willMoveSection:(NSInteger)section toSection:(NSInteger)newSection - (void)willMoveSection:(NSInteger)section toSection:(NSInteger)newSection
{ {
// Optional template hook for subclasses (See ASDataController+Subclasses.h) // Optional template hook for subclasses (See ASDataController+Subclasses.h)
@ -751,6 +781,16 @@ static void *kASSizingQueueContext = &kASSizingQueueContext;
// Optional template hook for subclasses (See ASDataController+Subclasses.h) // Optional template hook for subclasses (See ASDataController+Subclasses.h)
} }
- (void)prepareForReloadRowsAtIndexPaths:(NSArray<NSIndexPath *> *)indexPaths
{
// Optional template hook for subclasses (See ASDataController+Subclasses.h)
}
- (void)willReloadRowsAtIndexPaths:(NSArray<NSIndexPath *> *)indexPaths
{
// Optional template hook for subclasses (See ASDataController+Subclasses.h)
}
#pragma mark - Row Editing (External API) #pragma mark - Row Editing (External API)
- (void)insertRowsAtIndexPaths:(NSArray *)indexPaths withAnimationOptions:(ASDataControllerAnimationOptions)animationOptions - (void)insertRowsAtIndexPaths:(NSArray *)indexPaths withAnimationOptions:(ASDataControllerAnimationOptions)animationOptions
@ -813,7 +853,40 @@ static void *kASSizingQueueContext = &kASSizingQueueContext;
- (void)reloadRowsAtIndexPaths:(NSArray *)indexPaths withAnimationOptions:(ASDataControllerAnimationOptions)animationOptions - (void)reloadRowsAtIndexPaths:(NSArray *)indexPaths withAnimationOptions:(ASDataControllerAnimationOptions)animationOptions
{ {
ASDisplayNodeAssert(NO, @"ASDataController does not support %@. Call this on ASChangeSetDataController and the reload will be broken into delete & insert.", NSStringFromSelector(_cmd)); [self performEditCommandWithBlock:^{
ASDisplayNodeAssertMainThread();
LOG(@"Edit Command - reloadRows: %@", indexPaths);
[_editingTransactionQueue waitUntilAllOperationsAreFinished];
NSMutableArray<ASIndexedNodeContext *> *contexts = [[NSMutableArray alloc] initWithCapacity:indexPaths.count];
// Sort indexPath to avoid messing up the index when deleting
// FIXME: Shouldn't deletes be sorted in descending order?
NSArray *sortedIndexPaths = [indexPaths sortedArrayUsingSelector:@selector(compare:)];
id<ASEnvironment> environment = [self.environmentDelegate dataControllerEnvironment];
ASEnvironmentTraitCollection environmentTraitCollection = environment.environmentTraitCollection;
for (NSIndexPath *indexPath in sortedIndexPaths) {
ASCellNodeBlock nodeBlock = [_dataSource dataController:self nodeBlockAtIndexPath:indexPath];
ASSizeRange constrainedSize = [self constrainedSizeForNodeOfKind:ASDataControllerRowNodeKind atIndexPath:indexPath];
[contexts addObject:[[ASIndexedNodeContext alloc] initWithNodeBlock:nodeBlock
indexPath:indexPath
constrainedSize:constrainedSize
environmentTraitCollection:environmentTraitCollection]];
}
[self prepareForReloadRowsAtIndexPaths:indexPaths];
[_editingTransactionQueue addOperationWithBlock:^{
[self willReloadRowsAtIndexPaths:indexPaths];
LOG(@"Edit Transaction - reloadRows: %@", indexPaths);
[self _deleteNodesAtIndexPaths:sortedIndexPaths withAnimationOptions:animationOptions];
[self _batchLayoutNodesFromContexts:contexts withAnimationOptions:animationOptions];
}];
}];
} }
- (void)relayoutAllNodes - (void)relayoutAllNodes
@ -850,9 +923,8 @@ static void *kASSizingQueueContext = &kASSizingQueueContext;
for (ASCellNode *node in section) { for (ASCellNode *node in section) {
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:rowIndex inSection:sectionIndex]; NSIndexPath *indexPath = [NSIndexPath indexPathForRow:rowIndex inSection:sectionIndex];
ASSizeRange constrainedSize = [self constrainedSizeForNodeOfKind:kind atIndexPath:indexPath]; ASSizeRange constrainedSize = [self constrainedSizeForNodeOfKind:kind atIndexPath:indexPath];
CGRect frame = CGRectZero; CGSize size = [node measureWithSizeRange:constrainedSize].size;
frame.size = [node measureWithSizeRange:constrainedSize].size; node.frame = { .size = size };
node.frame = frame;
rowIndex += 1; rowIndex += 1;
} }
sectionIndex += 1; sectionIndex += 1;

View File

@ -118,15 +118,6 @@
return self; return self;
} }
- (BOOL)conformsToProtocol:(Protocol *)aProtocol
{
if (_target) {
return [_target conformsToProtocol:aProtocol];
} else {
return [super conformsToProtocol:aProtocol];
}
}
- (BOOL)respondsToSelector:(SEL)aSelector - (BOOL)respondsToSelector:(SEL)aSelector
{ {
if ([self interceptsSelector:aSelector]) { if ([self interceptsSelector:aSelector]) {

View File

@ -157,10 +157,6 @@ ASDISPLAYNODE_EXTERN_C_END
ASDN::MutexLocker l(lock);\ ASDN::MutexLocker l(lock);\
ASEnvironmentTraitCollection oldTraits = self.environmentState.environmentTraitCollection;\ ASEnvironmentTraitCollection oldTraits = self.environmentState.environmentTraitCollection;\
[super setEnvironmentState:environmentState];\ [super setEnvironmentState:environmentState];\
\
/* Extra Trait Collection Handling */\
/* If the node is not loaded yet don't do anything as otherwise the access of the view will trigger a load*/\
if (!self.isNodeLoaded) { return; } \
ASEnvironmentTraitCollection currentTraits = environmentState.environmentTraitCollection;\ ASEnvironmentTraitCollection currentTraits = environmentState.environmentTraitCollection;\
if (ASEnvironmentTraitCollectionIsEqualToASEnvironmentTraitCollection(currentTraits, oldTraits) == NO) {\ if (ASEnvironmentTraitCollectionIsEqualToASEnvironmentTraitCollection(currentTraits, oldTraits) == NO) {\
/* Must dispatch to main for self.view && [self.view.dataController completedNodes]*/ \ /* Must dispatch to main for self.view && [self.view.dataController completedNodes]*/ \

View File

@ -92,12 +92,12 @@
currPath.row++; currPath.row++;
// Once we reach the end of the section, advance to the next one. Keep advancing if the next section is zero-sized. // Once we reach the end of the section, advance to the next one. Keep advancing if the next section is zero-sized.
while (currPath.row >= [(NSArray *)completedNodes[currPath.section] count] && currPath.section < endPath.section) { while (currPath.row >= [(NSArray *)completedNodes[currPath.section] count] && currPath.section < completedNodes.count - 1) {
currPath.row = 0; currPath.row = 0;
currPath.section++; currPath.section++;
ASDisplayNodeAssert(currPath.section <= endPath.section, @"currPath should never reach a further section than endPath");
} }
} }
ASDisplayNodeAssert(currPath.section <= endPath.section, @"currPath should never reach a further section than endPath");
[indexPathSet addObject:[NSIndexPath indexPathWithASIndexPath:endPath]]; [indexPathSet addObject:[NSIndexPath indexPathWithASIndexPath:endPath]];

View File

@ -1,25 +0,0 @@
//
// NSIndexSet+ASHelpers.h
// AsyncDisplayKit
//
// Created by Adlai Holler on 6/23/16.
// Copyright © 2016 Facebook. All rights reserved.
//
#import <Foundation/Foundation.h>
@interface NSIndexSet (ASHelpers)
- (NSIndexSet *)as_indexesByMapping:(NSUInteger (^)(NSUInteger idx))block;
- (NSIndexSet *)as_intersectionWithIndexes:(NSIndexSet *)indexes;
/// Returns all the item indexes from the given index paths that are in the given section.
+ (NSIndexSet *)as_indexSetFromIndexPaths:(NSArray<NSIndexPath *> *)indexPaths inSection:(NSUInteger)section;
/// If you've got an old index, and you insert items using this index set, this returns the change to get to the new index.
- (NSUInteger)as_indexChangeByInsertingItemsBelowIndex:(NSUInteger)index;
- (NSString *)as_smallDescription;
@end

View File

@ -1,76 +0,0 @@
//
// NSIndexSet+ASHelpers.m
// AsyncDisplayKit
//
// Created by Adlai Holler on 6/23/16.
// Copyright © 2016 Facebook. All rights reserved.
//
#import <UIKit/UIKit.h>
#import "NSIndexSet+ASHelpers.h"
@implementation NSIndexSet (ASHelpers)
- (NSIndexSet *)as_indexesByMapping:(NSUInteger (^)(NSUInteger))block
{
NSMutableIndexSet *result = [NSMutableIndexSet indexSet];
[self enumerateIndexesUsingBlock:^(NSUInteger idx, __unused BOOL * _Nonnull stop) {
NSUInteger newIndex = block(idx);
if (newIndex != NSNotFound) {
[result addIndex:newIndex];
}
}];
return result;
}
- (NSIndexSet *)as_intersectionWithIndexes:(NSIndexSet *)indexes
{
NSMutableIndexSet *result = [NSMutableIndexSet indexSet];
[self enumerateRangesUsingBlock:^(NSRange range, BOOL * _Nonnull stop) {
[indexes enumerateRangesInRange:range options:kNilOptions usingBlock:^(NSRange range, BOOL * _Nonnull stop) {
[result addIndexesInRange:range];
}];
}];
return result;
}
+ (NSIndexSet *)as_indexSetFromIndexPaths:(NSArray<NSIndexPath *> *)indexPaths inSection:(NSUInteger)section
{
NSMutableIndexSet *result = [NSMutableIndexSet indexSet];
for (NSIndexPath *indexPath in indexPaths) {
if (indexPath.section == section) {
[result addIndex:indexPath.item];
}
}
return result;
}
- (NSUInteger)as_indexChangeByInsertingItemsBelowIndex:(NSUInteger)index
{
__block NSUInteger newIndex = index;
[self enumerateIndexesUsingBlock:^(NSUInteger idx, BOOL * _Nonnull stop) {
if (idx <= newIndex) {
newIndex += 1;
} else {
*stop = YES;
}
}];
return newIndex - index;
}
- (NSString *)as_smallDescription
{
NSMutableString *result = [NSMutableString stringWithString:@"{ "];
[self enumerateRangesUsingBlock:^(NSRange range, BOOL * _Nonnull stop) {
if (range.length == 1) {
[result appendFormat:@"%lu ", (unsigned long)range.location];
} else {
[result appendFormat:@"%lu-%lu ", (unsigned long)range.location, (unsigned long)NSMaxRange(range)];
}
}];
[result appendString:@"}"];
return result;
}
@end

View File

@ -13,8 +13,6 @@
#import <Foundation/Foundation.h> #import <Foundation/Foundation.h>
#import <AsyncDisplayKit/ASInternalHelpers.h> #import <AsyncDisplayKit/ASInternalHelpers.h>
NS_ASSUME_NONNULL_BEGIN
typedef NSUInteger ASDataControllerAnimationOptions; typedef NSUInteger ASDataControllerAnimationOptions;
typedef NS_ENUM(NSInteger, _ASHierarchyChangeType) { typedef NS_ENUM(NSInteger, _ASHierarchyChangeType) {
@ -23,8 +21,6 @@ typedef NS_ENUM(NSInteger, _ASHierarchyChangeType) {
_ASHierarchyChangeTypeInsert _ASHierarchyChangeTypeInsert
}; };
NSString *NSStringFromASHierarchyChangeType(_ASHierarchyChangeType changeType);
@interface _ASHierarchySectionChange : NSObject @interface _ASHierarchySectionChange : NSObject
// FIXME: Generalize this to `changeMetadata` dict? // FIXME: Generalize this to `changeMetadata` dict?
@ -38,11 +34,11 @@ NSString *NSStringFromASHierarchyChangeType(_ASHierarchyChangeType changeType);
@property (nonatomic, readonly) ASDataControllerAnimationOptions animationOptions; @property (nonatomic, readonly) ASDataControllerAnimationOptions animationOptions;
/// Index paths are sorted descending for changeType .Delete, ascending otherwise /// Index paths are sorted descending for changeType .Delete, ascending otherwise
@property (nonatomic, strong, readonly) NSArray<NSIndexPath *> *indexPaths; @property (nonatomic, strong, readonly) NSArray *indexPaths;
@property (nonatomic, readonly) _ASHierarchyChangeType changeType; @property (nonatomic, readonly) _ASHierarchyChangeType changeType;
+ (NSDictionary *)sectionToIndexSetMapFromChanges:(NSArray<_ASHierarchyItemChange *> *)changes ofType:(_ASHierarchyChangeType)changeType; + (NSDictionary *)sectionToIndexSetMapFromChanges:(NSArray *)changes ofType:(_ASHierarchyChangeType)changeType;
@end @end
@interface _ASHierarchyChangeSet : NSObject @interface _ASHierarchyChangeSet : NSObject
@ -51,6 +47,8 @@ NSString *NSStringFromASHierarchyChangeType(_ASHierarchyChangeType changeType);
@property (nonatomic, strong, readonly) NSIndexSet *deletedSections; @property (nonatomic, strong, readonly) NSIndexSet *deletedSections;
/// @precondition The change set must be completed. /// @precondition The change set must be completed.
@property (nonatomic, strong, readonly) NSIndexSet *insertedSections; @property (nonatomic, strong, readonly) NSIndexSet *insertedSections;
/// @precondition The change set must be completed.
@property (nonatomic, strong, readonly) NSIndexSet *reloadedSections;
/** /**
Get the section index after the update for the given section before the update. Get the section index after the update for the given section before the update.
@ -58,12 +56,11 @@ NSString *NSStringFromASHierarchyChangeType(_ASHierarchyChangeType changeType);
@precondition The change set must be completed. @precondition The change set must be completed.
@returns The new section index, or NSNotFound if the given section was deleted. @returns The new section index, or NSNotFound if the given section was deleted.
*/ */
- (NSUInteger)newSectionForOldSection:(NSUInteger)oldSection; - (NSInteger)newSectionForOldSection:(NSInteger)oldSection;
@property (nonatomic, readonly) BOOL completed; @property (nonatomic, readonly) BOOL completed;
/// Call this once the change set has been constructed to prevent future modifications to the changeset. Calling this more than once is a programmer error. /// Call this once the change set has been constructed to prevent future modifications to the changeset. Calling this more than once is a programmer error.
/// NOTE: Calling this method will cause the changeset to convert all reloads into delete/insert pairs.
- (void)markCompleted; - (void)markCompleted;
/** /**
@ -80,18 +77,13 @@ NSString *NSStringFromASHierarchyChangeType(_ASHierarchyChangeType changeType);
- Inserted sections, ascending order - Inserted sections, ascending order
- Inserted items, ascending order - Inserted items, ascending order
*/ */
- (nullable NSArray <_ASHierarchySectionChange *> *)sectionChangesOfType:(_ASHierarchyChangeType)changeType; - (NSArray /*<_ASHierarchySectionChange *>*/ *)sectionChangesOfType:(_ASHierarchyChangeType)changeType;
- (nullable NSArray <_ASHierarchyItemChange *> *)itemChangesOfType:(_ASHierarchyChangeType)changeType; - (NSArray /*<_ASHierarchyItemChange *>*/ *)itemChangesOfType:(_ASHierarchyChangeType)changeType;
/// Returns all item indexes affected by changes of the given type in the given section.
- (NSIndexSet *)indexesForItemChangesOfType:(_ASHierarchyChangeType)changeType inSection:(NSUInteger)section;
- (void)deleteSections:(NSIndexSet *)sections animationOptions:(ASDataControllerAnimationOptions)options; - (void)deleteSections:(NSIndexSet *)sections animationOptions:(ASDataControllerAnimationOptions)options;
- (void)insertSections:(NSIndexSet *)sections animationOptions:(ASDataControllerAnimationOptions)options; - (void)insertSections:(NSIndexSet *)sections animationOptions:(ASDataControllerAnimationOptions)options;
- (void)reloadSections:(NSIndexSet *)sections animationOptions:(ASDataControllerAnimationOptions)options; - (void)reloadSections:(NSIndexSet *)sections animationOptions:(ASDataControllerAnimationOptions)options;
- (void)insertItems:(NSArray<NSIndexPath *> *)indexPaths animationOptions:(ASDataControllerAnimationOptions)options; - (void)insertItems:(NSArray *)indexPaths animationOptions:(ASDataControllerAnimationOptions)options;
- (void)deleteItems:(NSArray<NSIndexPath *> *)indexPaths animationOptions:(ASDataControllerAnimationOptions)options; - (void)deleteItems:(NSArray *)indexPaths animationOptions:(ASDataControllerAnimationOptions)options;
- (void)reloadItems:(NSArray<NSIndexPath *> *)indexPaths animationOptions:(ASDataControllerAnimationOptions)options; - (void)reloadItems:(NSArray *)indexPaths animationOptions:(ASDataControllerAnimationOptions)options;
@end @end
NS_ASSUME_NONNULL_END

View File

@ -12,22 +12,6 @@
#import "_ASHierarchyChangeSet.h" #import "_ASHierarchyChangeSet.h"
#import "ASInternalHelpers.h" #import "ASInternalHelpers.h"
#import "NSIndexSet+ASHelpers.h"
#import "ASAssert.h"
NSString *NSStringFromASHierarchyChangeType(_ASHierarchyChangeType changeType)
{
switch (changeType) {
case _ASHierarchyChangeTypeInsert:
return @"Insert";
case _ASHierarchyChangeTypeDelete:
return @"Delete";
case _ASHierarchyChangeTypeReload:
return @"Reload";
default:
return @"(invalid)";
}
}
@interface _ASHierarchySectionChange () @interface _ASHierarchySectionChange ()
- (instancetype)initWithChangeType:(_ASHierarchyChangeType)changeType indexSet:(NSIndexSet *)indexSet animationOptions:(ASDataControllerAnimationOptions)animationOptions; - (instancetype)initWithChangeType:(_ASHierarchyChangeType)changeType indexSet:(NSIndexSet *)indexSet animationOptions:(ASDataControllerAnimationOptions)animationOptions;
@ -39,7 +23,7 @@ NSString *NSStringFromASHierarchyChangeType(_ASHierarchyChangeType changeType)
+ (void)sortAndCoalesceChanges:(NSMutableArray *)changes; + (void)sortAndCoalesceChanges:(NSMutableArray *)changes;
/// Returns all the indexes from all the `indexSet`s of the given `_ASHierarchySectionChange` objects. /// Returns all the indexes from all the `indexSet`s of the given `_ASHierarchySectionChange` objects.
+ (NSMutableIndexSet *)allIndexesInSectionChanges:(NSArray *)changes; + (NSMutableIndexSet *)allIndexesInChanges:(NSArray *)changes;
@end @end
@interface _ASHierarchyItemChange () @interface _ASHierarchyItemChange ()
@ -54,12 +38,12 @@ NSString *NSStringFromASHierarchyChangeType(_ASHierarchyChangeType changeType)
@interface _ASHierarchyChangeSet () @interface _ASHierarchyChangeSet ()
@property (nonatomic, strong, readonly) NSMutableArray<_ASHierarchyItemChange *> *insertItemChanges; @property (nonatomic, strong, readonly) NSMutableArray *insertItemChanges;
@property (nonatomic, strong, readonly) NSMutableArray<_ASHierarchyItemChange *> *deleteItemChanges; @property (nonatomic, strong, readonly) NSMutableArray *deleteItemChanges;
@property (nonatomic, strong, readonly) NSMutableArray<_ASHierarchyItemChange *> *reloadItemChanges; @property (nonatomic, strong, readonly) NSMutableArray *reloadItemChanges;
@property (nonatomic, strong, readonly) NSMutableArray<_ASHierarchySectionChange *> *insertSectionChanges; @property (nonatomic, strong, readonly) NSMutableArray *insertSectionChanges;
@property (nonatomic, strong, readonly) NSMutableArray<_ASHierarchySectionChange *> *deleteSectionChanges; @property (nonatomic, strong, readonly) NSMutableArray *deleteSectionChanges;
@property (nonatomic, strong, readonly) NSMutableArray<_ASHierarchySectionChange *> *reloadSectionChanges; @property (nonatomic, strong, readonly) NSMutableArray *reloadSectionChanges;
@end @end
@ -119,27 +103,21 @@ NSString *NSStringFromASHierarchyChangeType(_ASHierarchyChangeType changeType)
} }
} }
- (NSIndexSet *)indexesForItemChangesOfType:(_ASHierarchyChangeType)changeType inSection:(NSUInteger)section - (NSInteger)newSectionForOldSection:(NSInteger)oldSection
{ {
[self _ensureCompleted];
NSMutableIndexSet *result = [NSMutableIndexSet indexSet];
for (_ASHierarchyItemChange *change in [self itemChangesOfType:changeType]) {
[result addIndexes:[NSIndexSet as_indexSetFromIndexPaths:change.indexPaths inSection:section]];
}
return result;
}
- (NSUInteger)newSectionForOldSection:(NSUInteger)oldSection
{
ASDisplayNodeAssertNotNil(_deletedSections, @"Cannot call %@ before `markCompleted` returns.", NSStringFromSelector(_cmd));
ASDisplayNodeAssertNotNil(_insertedSections, @"Cannot call %@ before `markCompleted` returns.", NSStringFromSelector(_cmd));
[self _ensureCompleted]; [self _ensureCompleted];
if ([_deletedSections containsIndex:oldSection]) { if ([_deletedSections containsIndex:oldSection]) {
return NSNotFound; return NSNotFound;
} }
NSUInteger newIndex = oldSection - [_deletedSections countOfIndexesInRange:NSMakeRange(0, oldSection)]; __block NSInteger newIndex = oldSection - [_deletedSections countOfIndexesInRange:NSMakeRange(0, oldSection)];
newIndex += [_insertedSections as_indexChangeByInsertingItemsBelowIndex:newIndex]; [_insertedSections enumerateIndexesUsingBlock:^(NSUInteger idx, BOOL * _Nonnull stop) {
if (idx <= newIndex) {
newIndex += 1;
} else {
*stop = YES;
}
}];
return newIndex; return newIndex;
} }
@ -202,42 +180,42 @@ NSString *NSStringFromASHierarchyChangeType(_ASHierarchyChangeType changeType)
- (void)_sortAndCoalesceChangeArrays - (void)_sortAndCoalesceChangeArrays
{ {
@autoreleasepool { @autoreleasepool {
// Split reloaded sections into [delete(oldIndex), insert(newIndex)]
// Give these their "pre-reloads" values. Once we add in the reloads we'll re-process them.
_deletedSections = [_ASHierarchySectionChange allIndexesInSectionChanges:_deleteSectionChanges];
_insertedSections = [_ASHierarchySectionChange allIndexesInSectionChanges:_insertSectionChanges];
for (_ASHierarchySectionChange *change in _reloadSectionChanges) {
NSIndexSet *newSections = [change.indexSet as_indexesByMapping:^(NSUInteger idx) {
NSUInteger newSec = [self newSectionForOldSection:idx];
NSAssert(newSec != NSNotFound, @"Request to reload deleted section %lu", (unsigned long)idx);
return newSec;
}];
_ASHierarchySectionChange *deleteChange = [[_ASHierarchySectionChange alloc] initWithChangeType:_ASHierarchyChangeTypeDelete indexSet:change.indexSet animationOptions:change.animationOptions];
[_deleteSectionChanges addObject:deleteChange];
_ASHierarchySectionChange *insertChange = [[_ASHierarchySectionChange alloc] initWithChangeType:_ASHierarchyChangeTypeInsert indexSet:newSections animationOptions:change.animationOptions];
[_insertSectionChanges addObject:insertChange];
}
_reloadSectionChanges = nil;
[_ASHierarchySectionChange sortAndCoalesceChanges:_deleteSectionChanges]; [_ASHierarchySectionChange sortAndCoalesceChanges:_deleteSectionChanges];
[_ASHierarchySectionChange sortAndCoalesceChanges:_insertSectionChanges]; [_ASHierarchySectionChange sortAndCoalesceChanges:_insertSectionChanges];
_deletedSections = [_ASHierarchySectionChange allIndexesInSectionChanges:_deleteSectionChanges]; [_ASHierarchySectionChange sortAndCoalesceChanges:_reloadSectionChanges];
_insertedSections = [_ASHierarchySectionChange allIndexesInSectionChanges:_insertSectionChanges];
// Split reloaded items into [delete(oldIndexPath), insert(newIndexPath)] _deletedSections = [[_ASHierarchySectionChange allIndexesInChanges:_deleteSectionChanges] copy];
_insertedSections = [[_ASHierarchySectionChange allIndexesInChanges:_insertSectionChanges] copy];
_reloadedSections = [[_ASHierarchySectionChange allIndexesInChanges:_reloadSectionChanges] copy];
// These are invalid old section indexes.
NSMutableIndexSet *deletedOrReloaded = [_deletedSections mutableCopy];
[deletedOrReloaded addIndexes:_reloadedSections];
// These are invalid new section indexes.
NSMutableIndexSet *insertedOrReloaded = [_insertedSections mutableCopy];
// Get the new section that each reloaded section index corresponds to.
// Coalesce reload sections' indexes into deletes and inserts
[_reloadedSections enumerateIndexesUsingBlock:^(NSUInteger oldIndex, __unused BOOL * stop) {
NSUInteger newIndex = [self newSectionForOldSection:oldIndex];
if (newIndex != NSNotFound) {
[insertedOrReloaded addIndex:newIndex];
}
[deletedOrReloaded addIndex:oldIndex];
}];
_deletedSections = deletedOrReloaded;
_insertedSections = insertedOrReloaded;
_reloadedSections = nil;
// reload items changes need to be adjusted so that we access the correct indexPaths in the datasource
NSDictionary *insertedIndexPathsMap = [_ASHierarchyItemChange sectionToIndexSetMapFromChanges:_insertItemChanges ofType:_ASHierarchyChangeTypeInsert]; NSDictionary *insertedIndexPathsMap = [_ASHierarchyItemChange sectionToIndexSetMapFromChanges:_insertItemChanges ofType:_ASHierarchyChangeTypeInsert];
NSDictionary *deletedIndexPathsMap = [_ASHierarchyItemChange sectionToIndexSetMapFromChanges:_deleteItemChanges ofType:_ASHierarchyChangeTypeDelete]; NSDictionary *deletedIndexPathsMap = [_ASHierarchyItemChange sectionToIndexSetMapFromChanges:_deleteItemChanges ofType:_ASHierarchyChangeTypeDelete];
for (_ASHierarchyItemChange *change in _reloadItemChanges) { for (_ASHierarchyItemChange *change in _reloadItemChanges) {
NSAssert(change.changeType == _ASHierarchyChangeTypeReload, @"It must be a reload change to be in here"); NSAssert(change.changeType == _ASHierarchyChangeTypeReload, @"It must be a reload change to be in here");
NSMutableArray *newIndexPaths = [NSMutableArray arrayWithCapacity:change.indexPaths.count]; NSMutableArray *newIndexPaths = [NSMutableArray array];
// Every indexPaths in the change need to update its section and/or row // Every indexPaths in the change need to update its section and/or row
// depending on all the deletions and insertions // depending on all the deletions and insertions
@ -245,21 +223,39 @@ NSString *NSStringFromASHierarchyChangeType(_ASHierarchyChangeType changeType)
// - delete/reload indexPaths that are passed in should all be their current indexPaths // - delete/reload indexPaths that are passed in should all be their current indexPaths
// - insert indexPaths that are passed in should all be their future indexPaths after deletions // - insert indexPaths that are passed in should all be their future indexPaths after deletions
for (NSIndexPath *indexPath in change.indexPaths) { for (NSIndexPath *indexPath in change.indexPaths) {
NSUInteger section = [self newSectionForOldSection:indexPath.section]; __block NSUInteger section = indexPath.section;
NSUInteger item = indexPath.item; __block NSUInteger row = indexPath.row;
// Update section number based on section insertions/deletions that are above the current section
section -= [_deletedSections countOfIndexesInRange:NSMakeRange(0, section)];
[_insertedSections enumerateIndexesUsingBlock:^(NSUInteger idx, BOOL * _Nonnull stop) {
if (idx <= section) {
section += 1;
} else {
*stop = YES;
}
}];
// Update row number based on deletions that are above the current row in the current section // Update row number based on deletions that are above the current row in the current section
NSIndexSet *indicesDeletedInSection = deletedIndexPathsMap[@(indexPath.section)]; NSIndexSet *indicesDeletedInSection = deletedIndexPathsMap[@(indexPath.section)];
item -= [indicesDeletedInSection countOfIndexesInRange:NSMakeRange(0, item)]; row -= [indicesDeletedInSection countOfIndexesInRange:NSMakeRange(0, row)];
// Update row number based on insertions that are above the current row in the future section // Update row number based on insertions that are above the current row in the future section
NSIndexSet *indicesInsertedInSection = insertedIndexPathsMap[@(section)]; NSIndexSet *indicesInsertedInSection = insertedIndexPathsMap[@(section)];
item += [indicesInsertedInSection as_indexChangeByInsertingItemsBelowIndex:item]; [indicesInsertedInSection enumerateIndexesUsingBlock:^(NSUInteger idx, BOOL * _Nonnull stop) {
if (idx <= row) {
row += 1;
} else {
*stop = YES;
}
}];
NSIndexPath *newIndexPath = [NSIndexPath indexPathForItem:item inSection:section]; //TODO: reuse the old indexPath object if section and row aren't changed
NSIndexPath *newIndexPath = [NSIndexPath indexPathForRow:row inSection:section];
[newIndexPaths addObject:newIndexPath]; [newIndexPaths addObject:newIndexPath];
} }
// All reload changes are translated into deletes and inserts // All reload changes are coalesced into deletes and inserts
// We delete the items that needs reload together with other deleted items, at their original index // We delete the items that needs reload together with other deleted items, at their original index
_ASHierarchyItemChange *deleteItemChangeFromReloadChange = [[_ASHierarchyItemChange alloc] initWithChangeType:_ASHierarchyChangeTypeDelete indexPaths:change.indexPaths animationOptions:change.animationOptions presorted:NO]; _ASHierarchyItemChange *deleteItemChangeFromReloadChange = [[_ASHierarchyItemChange alloc] initWithChangeType:_ASHierarchyChangeTypeDelete indexPaths:change.indexPaths animationOptions:change.animationOptions presorted:NO];
[_deleteItemChanges addObject:deleteItemChangeFromReloadChange]; [_deleteItemChanges addObject:deleteItemChangeFromReloadChange];
@ -267,20 +263,16 @@ NSString *NSStringFromASHierarchyChangeType(_ASHierarchyChangeType changeType)
_ASHierarchyItemChange *insertItemChangeFromReloadChange = [[_ASHierarchyItemChange alloc] initWithChangeType:_ASHierarchyChangeTypeInsert indexPaths:newIndexPaths animationOptions:change.animationOptions presorted:NO]; _ASHierarchyItemChange *insertItemChangeFromReloadChange = [[_ASHierarchyItemChange alloc] initWithChangeType:_ASHierarchyChangeTypeInsert indexPaths:newIndexPaths animationOptions:change.animationOptions presorted:NO];
[_insertItemChanges addObject:insertItemChangeFromReloadChange]; [_insertItemChanges addObject:insertItemChangeFromReloadChange];
} }
_reloadItemChanges = nil; [_reloadItemChanges removeAllObjects];
// Ignore item deletes in reloaded/deleted sections. // Ignore item deletes in reloaded/deleted sections.
[_ASHierarchyItemChange sortAndCoalesceChanges:_deleteItemChanges ignoringChangesInSections:_deletedSections]; [_ASHierarchyItemChange sortAndCoalesceChanges:_deleteItemChanges ignoringChangesInSections:deletedOrReloaded];
// Ignore item inserts in reloaded(new)/inserted sections. // Ignore item inserts in reloaded(new)/inserted sections.
[_ASHierarchyItemChange sortAndCoalesceChanges:_insertItemChanges ignoringChangesInSections:_insertedSections]; [_ASHierarchyItemChange sortAndCoalesceChanges:_insertItemChanges ignoringChangesInSections:insertedOrReloaded];
} }
} }
- (NSString *)description
{
return [NSString stringWithFormat:@"<%@ %p: deletedSections=%@, insertedSections=%@, deletedItems=%@, insertedItems=%@>", NSStringFromClass(self.class), self, _deletedSections, _insertedSections, _deleteItemChanges, _insertItemChanges];
}
@end @end
@ -291,7 +283,6 @@ NSString *NSStringFromASHierarchyChangeType(_ASHierarchyChangeType changeType)
{ {
self = [super init]; self = [super init];
if (self) { if (self) {
ASDisplayNodeAssert(indexSet.count > 0, @"Request to create _ASHierarchySectionChange with no sections!");
_changeType = changeType; _changeType = changeType;
_indexSet = indexSet; _indexSet = indexSet;
_animationOptions = animationOptions; _animationOptions = animationOptions;
@ -355,7 +346,7 @@ NSString *NSStringFromASHierarchyChangeType(_ASHierarchyChangeType changeType)
[changes setArray:result]; [changes setArray:result];
} }
+ (NSMutableIndexSet *)allIndexesInSectionChanges:(NSArray<_ASHierarchySectionChange *> *)changes + (NSMutableIndexSet *)allIndexesInChanges:(NSArray *)changes
{ {
NSMutableIndexSet *indexes = [NSMutableIndexSet indexSet]; NSMutableIndexSet *indexes = [NSMutableIndexSet indexSet];
for (_ASHierarchySectionChange *change in changes) { for (_ASHierarchySectionChange *change in changes) {
@ -364,11 +355,6 @@ NSString *NSStringFromASHierarchyChangeType(_ASHierarchyChangeType changeType)
return indexes; return indexes;
} }
- (NSString *)description
{
return [NSString stringWithFormat:@"<%@: anim=%lu, type=%@, indexes=%@>", NSStringFromClass(self.class), (unsigned long)_animationOptions, NSStringFromASHierarchyChangeType(_changeType), [self.indexSet as_smallDescription]];
}
@end @end
@implementation _ASHierarchyItemChange @implementation _ASHierarchyItemChange
@ -377,7 +363,6 @@ NSString *NSStringFromASHierarchyChangeType(_ASHierarchyChangeType changeType)
{ {
self = [super init]; self = [super init];
if (self) { if (self) {
ASDisplayNodeAssert(indexPaths.count > 0, @"Request to create _ASHierarchyItemChange with no items!");
_changeType = changeType; _changeType = changeType;
if (presorted) { if (presorted) {
_indexPaths = indexPaths; _indexPaths = indexPaths;
@ -402,9 +387,9 @@ NSString *NSStringFromASHierarchyChangeType(_ASHierarchyChangeType changeType)
NSNumber *sectionKey = @(indexPath.section); NSNumber *sectionKey = @(indexPath.section);
NSMutableIndexSet *indexSet = sectionToIndexSetMap[sectionKey]; NSMutableIndexSet *indexSet = sectionToIndexSetMap[sectionKey];
if (indexSet) { if (indexSet) {
[indexSet addIndex:indexPath.item]; [indexSet addIndex:indexPath.row];
} else { } else {
indexSet = [NSMutableIndexSet indexSetWithIndex:indexPath.item]; indexSet = [NSMutableIndexSet indexSetWithIndex:indexPath.row];
sectionToIndexSetMap[sectionKey] = indexSet; sectionToIndexSetMap[sectionKey] = indexSet;
} }
} }
@ -412,7 +397,7 @@ NSString *NSStringFromASHierarchyChangeType(_ASHierarchyChangeType changeType)
return sectionToIndexSetMap; return sectionToIndexSetMap;
} }
+ (void)sortAndCoalesceChanges:(NSMutableArray *)changes ignoringChangesInSections:(NSIndexSet *)ignoredSections + (void)sortAndCoalesceChanges:(NSMutableArray *)changes ignoringChangesInSections:(NSIndexSet *)sections
{ {
if (changes.count < 1) { if (changes.count < 1) {
return; return;
@ -426,9 +411,12 @@ NSString *NSStringFromASHierarchyChangeType(_ASHierarchyChangeType changeType)
// All changed index paths, sorted // All changed index paths, sorted
NSMutableArray *allIndexPaths = [NSMutableArray new]; NSMutableArray *allIndexPaths = [NSMutableArray new];
NSPredicate *indexPathInValidSection = [NSPredicate predicateWithBlock:^BOOL(NSIndexPath *indexPath, __unused NSDictionary *_) {
return ![sections containsIndex:indexPath.section];
}];
for (_ASHierarchyItemChange *change in changes) { for (_ASHierarchyItemChange *change in changes) {
for (NSIndexPath *indexPath in change.indexPaths) { for (NSIndexPath *indexPath in change.indexPaths) {
if (![ignoredSections containsIndex:indexPath.section]) { if ([indexPathInValidSection evaluateWithObject:indexPath]) {
animationOptions[indexPath] = @(change.animationOptions); animationOptions[indexPath] = @(change.animationOptions);
[allIndexPaths addObject:indexPath]; [allIndexPaths addObject:indexPath];
} }
@ -471,9 +459,4 @@ NSString *NSStringFromASHierarchyChangeType(_ASHierarchyChangeType changeType)
[changes setArray:result]; [changes setArray:result];
} }
- (NSString *)description
{
return [NSString stringWithFormat:@"<%@: anim=%lu, type=%@, indexPaths=%@>", NSStringFromClass(self.class), (unsigned long)_animationOptions, NSStringFromASHierarchyChangeType(_changeType), self.indexPaths];
}
@end @end

View File

@ -200,44 +200,4 @@
XCTAssertTrue([(ASTextCellNodeWithSetSelectedCounter *)node setSelectedCounter] == 6, @"setSelected: should not be called on node multiple times."); XCTAssertTrue([(ASTextCellNodeWithSetSelectedCounter *)node setSelectedCounter] == 6, @"setSelected: should not be called on node multiple times.");
} }
- (void)testTuningParametersWithExplicitRangeMode
{
UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init];
ASCollectionView *collectionView = [[ASCollectionView alloc] initWithFrame:CGRectZero collectionViewLayout:layout];
ASRangeTuningParameters minimumRenderParams = { .leadingBufferScreenfuls = 0.1, .trailingBufferScreenfuls = 0.1 };
ASRangeTuningParameters minimumPreloadParams = { .leadingBufferScreenfuls = 0.1, .trailingBufferScreenfuls = 0.1 };
ASRangeTuningParameters fullRenderParams = { .leadingBufferScreenfuls = 0.5, .trailingBufferScreenfuls = 0.5 };
ASRangeTuningParameters fullPreloadParams = { .leadingBufferScreenfuls = 1, .trailingBufferScreenfuls = 0.5 };
[collectionView setTuningParameters:minimumRenderParams forRangeMode:ASLayoutRangeModeMinimum rangeType:ASLayoutRangeTypeDisplay];
[collectionView setTuningParameters:minimumPreloadParams forRangeMode:ASLayoutRangeModeMinimum rangeType:ASLayoutRangeTypeFetchData];
[collectionView setTuningParameters:fullRenderParams forRangeMode:ASLayoutRangeModeFull rangeType:ASLayoutRangeTypeDisplay];
[collectionView setTuningParameters:fullPreloadParams forRangeMode:ASLayoutRangeModeFull rangeType:ASLayoutRangeTypeFetchData];
XCTAssertTrue(ASRangeTuningParametersEqualToRangeTuningParameters(minimumRenderParams,
[collectionView tuningParametersForRangeMode:ASLayoutRangeModeMinimum rangeType:ASLayoutRangeTypeDisplay]));
XCTAssertTrue(ASRangeTuningParametersEqualToRangeTuningParameters(minimumPreloadParams,
[collectionView tuningParametersForRangeMode:ASLayoutRangeModeMinimum rangeType:ASLayoutRangeTypeFetchData]));
XCTAssertTrue(ASRangeTuningParametersEqualToRangeTuningParameters(fullRenderParams,
[collectionView tuningParametersForRangeMode:ASLayoutRangeModeFull rangeType:ASLayoutRangeTypeDisplay]));
XCTAssertTrue(ASRangeTuningParametersEqualToRangeTuningParameters(fullPreloadParams,
[collectionView tuningParametersForRangeMode:ASLayoutRangeModeFull rangeType:ASLayoutRangeTypeFetchData]));
}
- (void)testTuningParameters
{
UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init];
ASCollectionView *collectionView = [[ASCollectionView alloc] initWithFrame:CGRectZero collectionViewLayout:layout];
ASRangeTuningParameters renderParams = { .leadingBufferScreenfuls = 1.2, .trailingBufferScreenfuls = 3.2 };
ASRangeTuningParameters preloadParams = { .leadingBufferScreenfuls = 4.3, .trailingBufferScreenfuls = 2.3 };
[collectionView setTuningParameters:renderParams forRangeType:ASLayoutRangeTypeDisplay];
[collectionView setTuningParameters:preloadParams forRangeType:ASLayoutRangeTypeFetchData];
XCTAssertTrue(ASRangeTuningParametersEqualToRangeTuningParameters(renderParams, [collectionView tuningParametersForRangeType:ASLayoutRangeTypeDisplay]));
XCTAssertTrue(ASRangeTuningParametersEqualToRangeTuningParameters(preloadParams, [collectionView tuningParametersForRangeType:ASLayoutRangeTypeFetchData]));
}
@end @end

View File

@ -128,6 +128,7 @@
return textCellNode; return textCellNode;
} }
- (ASCellNodeBlock)tableView:(ASTableView *)tableView nodeBlockForRowAtIndexPath:(NSIndexPath *)indexPath - (ASCellNodeBlock)tableView:(ASTableView *)tableView nodeBlockForRowAtIndexPath:(NSIndexPath *)indexPath
{ {
return ^{ return ^{
@ -139,52 +140,12 @@
@end @end
@interface ASTableViewFilledDelegate : NSObject <ASTableViewDelegate>
@end
@implementation ASTableViewFilledDelegate
- (ASSizeRange)tableView:(ASTableView *)tableView constrainedSizeForRowAtIndexPath:(NSIndexPath *)indexPath
{
return ASSizeRangeMakeExactSize(CGSizeMake(10, 42));
}
@end
@interface ASTableViewTests : XCTestCase @interface ASTableViewTests : XCTestCase
@property (atomic, retain) ASTableView *testTableView; @property (atomic, retain) ASTableView *testTableView;
@end @end
@implementation ASTableViewTests @implementation ASTableViewTests
- (void)testConstrainedSizeForRowAtIndexPath
{
// Initial width of the table view is non-zero and all nodes are measured with this size.
// Any subsequence size change must trigger a relayout.
// Width and height are swapped so that a later size change will simulate a rotation
ASTestTableView *tableView = [[ASTestTableView alloc] __initWithFrame:CGRectMake(0, 0, 100, 400)
style:UITableViewStylePlain];
ASTableViewFilledDelegate *delegate = [ASTableViewFilledDelegate new];
ASTableViewFilledDataSource *dataSource = [ASTableViewFilledDataSource new];
tableView.asyncDelegate = delegate;
tableView.asyncDataSource = dataSource;
[tableView reloadDataImmediately];
[tableView setNeedsLayout];
[tableView layoutIfNeeded];
for (int section = 0; section < NumberOfSections; section++) {
for (int row = 0; row < NumberOfRowsPerSection; row++) {
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:row inSection:section];
CGRect rect = [tableView rectForRowAtIndexPath:indexPath];
XCTAssertEqual(rect.size.width, 100); // specified width should be ignored for table
XCTAssertEqual(rect.size.height, 42);
}
}
}
// TODO: Convert this to ARC. // TODO: Convert this to ARC.
- (void)DISABLED_testTableViewDoesNotRetainItselfAndDelegate - (void)DISABLED_testTableViewDoesNotRetainItselfAndDelegate
{ {

View File

@ -8,7 +8,6 @@
@import XCTest; @import XCTest;
#import <AsyncDisplayKit/AsyncDisplayKit.h> #import <AsyncDisplayKit/AsyncDisplayKit.h>
#import "ASTableViewInternal.h"
// Set to 1 to use UITableView and see if the issue still exists. // Set to 1 to use UITableView and see if the issue still exists.
#define USE_UIKIT_REFERENCE 0 #define USE_UIKIT_REFERENCE 0
@ -20,8 +19,8 @@
#define TableView ASTableView #define TableView ASTableView
#endif #endif
#define kInitialSectionCount 10 #define kInitialSectionCount 20
#define kInitialItemCount 10 #define kInitialItemCount 20
#define kMinimumItemCount 5 #define kMinimumItemCount 5
#define kMinimumSectionCount 3 #define kMinimumSectionCount 3
#define kFickleness 0.1 #define kFickleness 0.1
@ -146,7 +145,7 @@ static volatile int32_t ASThrashTestSectionNextID = 1;
} }
- (NSString *)description { - (NSString *)description {
return [NSString stringWithFormat:@"<Section %lu: itemCount=%lu, items=%@>", (unsigned long)_sectionID, (unsigned long)self.items.count, ASThrashArrayDescription(self.items)]; return [NSString stringWithFormat:@"<Section %lu: itemCount=%lu>", (unsigned long)_sectionID, (unsigned long)self.items.count];
} }
- (id)copyWithZone:(NSZone *)zone { - (id)copyWithZone:(NSZone *)zone {
@ -446,22 +445,17 @@ static NSInteger ASThrashUpdateCurrentSerializationVersion = 1;
@implementation ASTableViewThrashTests { @implementation ASTableViewThrashTests {
// The current update, which will be logged in case of a failure. // The current update, which will be logged in case of a failure.
ASThrashUpdate *_update; ASThrashUpdate *_update;
BOOL _failed;
} }
#pragma mark Overrides #pragma mark Overrides
- (void)tearDown { - (void)tearDown {
if (_failed && _update != nil) {
NSLog(@"Failed update %@: %@", _update, _update.logFriendlyBase64Representation);
}
_failed = NO;
_update = nil; _update = nil;
} }
// NOTE: Despite the documentation, this is not always called if an exception is caught. // NOTE: Despite the documentation, this is not always called if an exception is caught.
- (void)recordFailureWithDescription:(NSString *)description inFile:(NSString *)filePath atLine:(NSUInteger)lineNumber expected:(BOOL)expected { - (void)recordFailureWithDescription:(NSString *)description inFile:(NSString *)filePath atLine:(NSUInteger)lineNumber expected:(BOOL)expected {
_failed = YES; [self logCurrentUpdateIfNeeded];
[super recordFailureWithDescription:description inFile:filePath atLine:lineNumber expected:expected]; [super recordFailureWithDescription:description inFile:filePath atLine:lineNumber expected:expected];
} }
@ -483,12 +477,11 @@ static NSInteger ASThrashUpdateCurrentSerializationVersion = 1;
} }
ASThrashDataSource *ds = [[ASThrashDataSource alloc] initWithData:_update.oldData]; ASThrashDataSource *ds = [[ASThrashDataSource alloc] initWithData:_update.oldData];
ds.tableView.test_enableSuperUpdateCallLogging = YES;
[self applyUpdate:_update toDataSource:ds]; [self applyUpdate:_update toDataSource:ds];
[self verifyDataSource:ds]; [self verifyDataSource:ds];
} }
- (void)testThrashingWildly { - (void)DISABLED_testThrashingWildly {
for (NSInteger i = 0; i < kThrashingIterationCount; i++) { for (NSInteger i = 0; i < kThrashingIterationCount; i++) {
[self setUp]; [self setUp];
ASThrashDataSource *ds = [[ASThrashDataSource alloc] initWithData:[ASThrashTestSection sectionsWithCount:kInitialSectionCount]]; ASThrashDataSource *ds = [[ASThrashDataSource alloc] initWithData:[ASThrashTestSection sectionsWithCount:kInitialSectionCount]];
@ -502,6 +495,12 @@ static NSInteger ASThrashUpdateCurrentSerializationVersion = 1;
#pragma mark Helpers #pragma mark Helpers
- (void)logCurrentUpdateIfNeeded {
if (_update != nil) {
NSLog(@"Failed update %@: %@", _update, _update.logFriendlyBase64Representation);
}
}
- (void)applyUpdate:(ASThrashUpdate *)update toDataSource:(ASThrashDataSource *)dataSource { - (void)applyUpdate:(ASThrashUpdate *)update toDataSource:(ASThrashDataSource *)dataSource {
TableView *tableView = dataSource.tableView; TableView *tableView = dataSource.tableView;
@ -534,7 +533,7 @@ static NSInteger ASThrashUpdateCurrentSerializationVersion = 1;
[tableView waitUntilAllUpdatesAreCommitted]; [tableView waitUntilAllUpdatesAreCommitted];
#endif #endif
} @catch (NSException *exception) { } @catch (NSException *exception) {
_failed = YES; [self logCurrentUpdateIfNeeded];
@throw exception; @throw exception;
} }
} }
@ -554,7 +553,7 @@ static NSInteger ASThrashUpdateCurrentSerializationVersion = 1;
XCTAssertEqual([tableView rectForRowAtIndexPath:indexPath].size.height, item.rowHeight); XCTAssertEqual([tableView rectForRowAtIndexPath:indexPath].size.height, item.rowHeight);
#else #else
ASThrashTestNode *node = (ASThrashTestNode *)[tableView nodeForRowAtIndexPath:indexPath]; ASThrashTestNode *node = (ASThrashTestNode *)[tableView nodeForRowAtIndexPath:indexPath];
XCTAssertEqualObjects(node.item, item, @"Wrong node at index path %@", indexPath); XCTAssertEqual(node.item, item);
#endif #endif
} }
} }

File diff suppressed because one or more lines are too long

View File

@ -10,7 +10,7 @@
[![Carthage compatible](https://img.shields.io/badge/Carthage-compatible-59C939.svg?style=flat)](https://github.com/Carthage/Carthage) [![Carthage compatible](https://img.shields.io/badge/Carthage-compatible-59C939.svg?style=flat)](https://github.com/Carthage/Carthage)
[![Build Status](https://travis-ci.org/facebook/AsyncDisplayKit.svg)](https://travis-ci.org/facebook/AsyncDisplayKit) [![Build Status](https://travis-ci.org/facebook/AsyncDisplayKit.svg)](https://travis-ci.org/facebook/AsyncDisplayKit)
[![License](https://img.shields.io/cocoapods/l/AsyncDisplayKit.svg)](https://github.com/facebook/AsyncDisplayKit/blob/master/LICENSE) [![License](https://img.shields.io/cocoapods/l/AsyncDisplayKit.svg)](https://github.com/facebook/AsyncDisplayKit/blob/master/LICENSE)
AsyncDisplayKit is an iOS framework that keeps even the most complex user AsyncDisplayKit is an iOS framework that keeps even the most complex user
interfaces smooth and responsive. It was originally built to make Facebook's interfaces smooth and responsive. It was originally built to make Facebook's
@ -18,14 +18,14 @@ interfaces smooth and responsive. It was originally built to make Facebook's
[pop](https://github.com/facebook/pop)'s physics-based animations &mdash; but [pop](https://github.com/facebook/pop)'s physics-based animations &mdash; but
it's just as powerful with UIKit Dynamics and conventional app designs. it's just as powerful with UIKit Dynamics and conventional app designs.
### Quick start ### Quick start
ASDK is available on [CocoaPods](http://cocoapods.org). Add the following to your Podfile: ASDK is available on [CocoaPods](http://cocoapods.org). Add the following to your Podfile:
```ruby ```ruby
pod 'AsyncDisplayKit' pod 'AsyncDisplayKit'
``` ```
(ASDK can also be used as a regular static library: Copy the project to your (ASDK can also be used as a regular static library: Copy the project to your
codebase manually, adding `AsyncDisplayKit.xcodeproj` to your workspace. Add codebase manually, adding `AsyncDisplayKit.xcodeproj` to your workspace. Add
`libAsyncDisplayKit.a`, MapKit, AssetsLibrary, and Photos to the "Link Binary With `libAsyncDisplayKit.a`, MapKit, AssetsLibrary, and Photos to the "Link Binary With
@ -46,7 +46,7 @@ CALayers:
You can construct entire node hierarchies in parallel, or instantiate and size You can construct entire node hierarchies in parallel, or instantiate and size
a single node on a background thread &mdash; for example, you could do a single node on a background thread &mdash; for example, you could do
something like this in a UIViewController: something like this in a UIViewController:
```objective-c ```objective-c
dispatch_async(_backgroundQueue, ^{ dispatch_async(_backgroundQueue, ^{

View File

@ -36,46 +36,6 @@ if [ "$MODE" = "tests" ]; then
exit 0 exit 0
fi fi
if [ "$MODE" = "examples" ]; then
echo "Verifying that all AsyncDisplayKit examples compile."
for example in examples/*/; do
echo "Building (examples) $example."
if [ -f "${example}/Podfile" ]; then
echo "Using CocoaPods"
pod install --project-directory=$example
set -o pipefail && xcodebuild \
-workspace "${example}/Sample.xcworkspace" \
-scheme Sample \
-sdk "$SDK" \
-destination "$PLATFORM" \
-derivedDataPath ~/ \
build | xcpretty $FORMATTER
elif [ -f "${example}/Cartfile" ]; then
echo "Using Carthage"
local_repo=`pwd`
current_branch=`git rev-parse --abbrev-ref HEAD`
cd $example
echo "git \"file://${local_repo}\" \"${current_branch}\"" > "Cartfile"
carthage update --platform iOS
set -o pipefail && xcodebuild \
-project "Sample.xcodeproj" \
-scheme Sample \
-sdk "$SDK" \
-destination "$PLATFORM" \
build | xcpretty $FORMATTER
cd ../..
fi
done
trap - EXIT
exit 0
fi
if [ "$MODE" = "examples-pt1" ]; then if [ "$MODE" = "examples-pt1" ]; then
echo "Verifying that all AsyncDisplayKit examples compile." echo "Verifying that all AsyncDisplayKit examples compile."