mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-23 14:45:21 +00:00
[ASRangeController] Initial implementation of functional-style, ASInterfaceState-based range controller.
This commit is contained in:
@@ -459,6 +459,7 @@
|
|||||||
D785F6631A74327E00291744 /* ASScrollNode.m in Sources */ = {isa = PBXBuildFile; fileRef = D785F6611A74327E00291744 /* ASScrollNode.m */; };
|
D785F6631A74327E00291744 /* ASScrollNode.m in Sources */ = {isa = PBXBuildFile; fileRef = D785F6611A74327E00291744 /* ASScrollNode.m */; };
|
||||||
DB7121BCD50849C498C886FB /* libPods-AsyncDisplayKitTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = EFA731F0396842FF8AB635EE /* libPods-AsyncDisplayKitTests.a */; };
|
DB7121BCD50849C498C886FB /* libPods-AsyncDisplayKitTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = EFA731F0396842FF8AB635EE /* libPods-AsyncDisplayKitTests.a */; };
|
||||||
DE040EF91C2B40AC004692FF /* ASCollectionViewFlowLayoutInspector.h in Headers */ = {isa = PBXBuildFile; fileRef = 251B8EF41BBB3D690087C538 /* ASCollectionViewFlowLayoutInspector.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
DE040EF91C2B40AC004692FF /* ASCollectionViewFlowLayoutInspector.h in Headers */ = {isa = PBXBuildFile; fileRef = 251B8EF41BBB3D690087C538 /* ASCollectionViewFlowLayoutInspector.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||||
|
DE0702FC1C3671E900D7DE62 /* libAsyncDisplayKit.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 058D09AC195D04C000B7D73C /* libAsyncDisplayKit.a */; };
|
||||||
DE6EA3221C14000600183B10 /* ASDisplayNode+FrameworkPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = DE6EA3211C14000600183B10 /* ASDisplayNode+FrameworkPrivate.h */; };
|
DE6EA3221C14000600183B10 /* ASDisplayNode+FrameworkPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = DE6EA3211C14000600183B10 /* ASDisplayNode+FrameworkPrivate.h */; };
|
||||||
DE6EA3231C14000600183B10 /* ASDisplayNode+FrameworkPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = DE6EA3211C14000600183B10 /* ASDisplayNode+FrameworkPrivate.h */; };
|
DE6EA3231C14000600183B10 /* ASDisplayNode+FrameworkPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = DE6EA3211C14000600183B10 /* ASDisplayNode+FrameworkPrivate.h */; };
|
||||||
DE8BEAC11C2DF3FC00D57C12 /* ASDelegateProxy.h in Headers */ = {isa = PBXBuildFile; fileRef = DE8BEABF1C2DF3FC00D57C12 /* ASDelegateProxy.h */; };
|
DE8BEAC11C2DF3FC00D57C12 /* ASDelegateProxy.h in Headers */ = {isa = PBXBuildFile; fileRef = DE8BEABF1C2DF3FC00D57C12 /* ASDelegateProxy.h */; };
|
||||||
@@ -469,6 +470,10 @@
|
|||||||
DECBD6E81BE56E1900CF4905 /* ASButtonNode.h in Headers */ = {isa = PBXBuildFile; fileRef = DECBD6E51BE56E1900CF4905 /* ASButtonNode.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
DECBD6E81BE56E1900CF4905 /* ASButtonNode.h in Headers */ = {isa = PBXBuildFile; fileRef = DECBD6E51BE56E1900CF4905 /* ASButtonNode.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||||
DECBD6E91BE56E1900CF4905 /* ASButtonNode.mm in Sources */ = {isa = PBXBuildFile; fileRef = DECBD6E61BE56E1900CF4905 /* ASButtonNode.mm */; };
|
DECBD6E91BE56E1900CF4905 /* ASButtonNode.mm in Sources */ = {isa = PBXBuildFile; fileRef = DECBD6E61BE56E1900CF4905 /* ASButtonNode.mm */; };
|
||||||
DECBD6EA1BE56E1900CF4905 /* ASButtonNode.mm in Sources */ = {isa = PBXBuildFile; fileRef = DECBD6E61BE56E1900CF4905 /* ASButtonNode.mm */; };
|
DECBD6EA1BE56E1900CF4905 /* ASButtonNode.mm in Sources */ = {isa = PBXBuildFile; fileRef = DECBD6E61BE56E1900CF4905 /* ASButtonNode.mm */; };
|
||||||
|
DECC2ECD1C35C1C600388446 /* ASRangeControllerBeta.h in Headers */ = {isa = PBXBuildFile; fileRef = DECC2ECB1C35C1C600388446 /* ASRangeControllerBeta.h */; };
|
||||||
|
DECC2ECE1C35C1C600388446 /* ASRangeControllerBeta.h in Headers */ = {isa = PBXBuildFile; fileRef = DECC2ECB1C35C1C600388446 /* ASRangeControllerBeta.h */; };
|
||||||
|
DECC2ECF1C35C1C600388446 /* ASRangeControllerBeta.mm in Sources */ = {isa = PBXBuildFile; fileRef = DECC2ECC1C35C1C600388446 /* ASRangeControllerBeta.mm */; };
|
||||||
|
DECC2ED01C35C1C600388446 /* ASRangeControllerBeta.mm in Sources */ = {isa = PBXBuildFile; fileRef = DECC2ECC1C35C1C600388446 /* ASRangeControllerBeta.mm */; };
|
||||||
/* End PBXBuildFile section */
|
/* End PBXBuildFile section */
|
||||||
|
|
||||||
/* Begin PBXContainerItemProxy section */
|
/* Begin PBXContainerItemProxy section */
|
||||||
@@ -762,6 +767,8 @@
|
|||||||
DE8BEAC01C2DF3FC00D57C12 /* ASDelegateProxy.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASDelegateProxy.m; sourceTree = "<group>"; };
|
DE8BEAC01C2DF3FC00D57C12 /* ASDelegateProxy.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASDelegateProxy.m; sourceTree = "<group>"; };
|
||||||
DECBD6E51BE56E1900CF4905 /* ASButtonNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASButtonNode.h; sourceTree = "<group>"; };
|
DECBD6E51BE56E1900CF4905 /* ASButtonNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASButtonNode.h; sourceTree = "<group>"; };
|
||||||
DECBD6E61BE56E1900CF4905 /* ASButtonNode.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASButtonNode.mm; sourceTree = "<group>"; };
|
DECBD6E61BE56E1900CF4905 /* ASButtonNode.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASButtonNode.mm; sourceTree = "<group>"; };
|
||||||
|
DECC2ECB1C35C1C600388446 /* ASRangeControllerBeta.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASRangeControllerBeta.h; sourceTree = "<group>"; };
|
||||||
|
DECC2ECC1C35C1C600388446 /* ASRangeControllerBeta.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASRangeControllerBeta.mm; sourceTree = "<group>"; };
|
||||||
EFA731F0396842FF8AB635EE /* libPods-AsyncDisplayKitTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-AsyncDisplayKitTests.a"; sourceTree = BUILT_PRODUCTS_DIR; };
|
EFA731F0396842FF8AB635EE /* libPods-AsyncDisplayKitTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-AsyncDisplayKitTests.a"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
FB07EABBCF28656C6297BC2D /* Pods-AsyncDisplayKitTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-AsyncDisplayKitTests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-AsyncDisplayKitTests/Pods-AsyncDisplayKitTests.debug.xcconfig"; sourceTree = "<group>"; };
|
FB07EABBCF28656C6297BC2D /* Pods-AsyncDisplayKitTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-AsyncDisplayKitTests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-AsyncDisplayKitTests/Pods-AsyncDisplayKitTests.debug.xcconfig"; sourceTree = "<group>"; };
|
||||||
/* End PBXFileReference section */
|
/* End PBXFileReference section */
|
||||||
@@ -771,6 +778,7 @@
|
|||||||
isa = PBXFrameworksBuildPhase;
|
isa = PBXFrameworksBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
|
DE0702FC1C3671E900D7DE62 /* libAsyncDisplayKit.a in Frameworks */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
@@ -1029,6 +1037,8 @@
|
|||||||
058D09E9195D050800B7D73C /* ASMutableAttributedStringBuilder.m */,
|
058D09E9195D050800B7D73C /* ASMutableAttributedStringBuilder.m */,
|
||||||
055F1A3619ABD413004DAFF1 /* ASRangeController.h */,
|
055F1A3619ABD413004DAFF1 /* ASRangeController.h */,
|
||||||
055F1A3719ABD413004DAFF1 /* ASRangeController.mm */,
|
055F1A3719ABD413004DAFF1 /* ASRangeController.mm */,
|
||||||
|
DECC2ECB1C35C1C600388446 /* ASRangeControllerBeta.h */,
|
||||||
|
DECC2ECC1C35C1C600388446 /* ASRangeControllerBeta.mm */,
|
||||||
292C599C1A956527007E5DD6 /* ASRangeHandler.h */,
|
292C599C1A956527007E5DD6 /* ASRangeHandler.h */,
|
||||||
258FF4251C0D152600A83844 /* ASRangeHandlerVisible.h */,
|
258FF4251C0D152600A83844 /* ASRangeHandlerVisible.h */,
|
||||||
258FF4261C0D152600A83844 /* ASRangeHandlerVisible.mm */,
|
258FF4261C0D152600A83844 /* ASRangeHandlerVisible.mm */,
|
||||||
@@ -1315,6 +1325,7 @@
|
|||||||
9C65A72A1BA8EA4D0084DA91 /* ASLayoutOptionsPrivate.h in Headers */,
|
9C65A72A1BA8EA4D0084DA91 /* ASLayoutOptionsPrivate.h in Headers */,
|
||||||
292C599F1A956527007E5DD6 /* ASLayoutRangeType.h in Headers */,
|
292C599F1A956527007E5DD6 /* ASLayoutRangeType.h in Headers */,
|
||||||
257754B61BEE44CD00737CA5 /* ASEqualityHashHelpers.h in Headers */,
|
257754B61BEE44CD00737CA5 /* ASEqualityHashHelpers.h in Headers */,
|
||||||
|
DECC2ECD1C35C1C600388446 /* ASRangeControllerBeta.h in Headers */,
|
||||||
ACF6ED261B17843500DA7C62 /* ASLayoutSpec.h in Headers */,
|
ACF6ED261B17843500DA7C62 /* ASLayoutSpec.h in Headers */,
|
||||||
ACF6ED4D1B17847A00DA7C62 /* ASLayoutSpecUtilities.h in Headers */,
|
ACF6ED4D1B17847A00DA7C62 /* ASLayoutSpecUtilities.h in Headers */,
|
||||||
AC026B6F1BD57DBF00BBC17E /* _ASHierarchyChangeSet.h in Headers */,
|
AC026B6F1BD57DBF00BBC17E /* _ASHierarchyChangeSet.h in Headers */,
|
||||||
@@ -1373,6 +1384,7 @@
|
|||||||
B350623C1B010EFD0018CF92 /* _ASAsyncTransaction.h in Headers */,
|
B350623C1B010EFD0018CF92 /* _ASAsyncTransaction.h in Headers */,
|
||||||
B350623E1B010EFD0018CF92 /* _ASAsyncTransactionContainer+Private.h in Headers */,
|
B350623E1B010EFD0018CF92 /* _ASAsyncTransactionContainer+Private.h in Headers */,
|
||||||
B350623F1B010EFD0018CF92 /* _ASAsyncTransactionContainer.h in Headers */,
|
B350623F1B010EFD0018CF92 /* _ASAsyncTransactionContainer.h in Headers */,
|
||||||
|
DECC2ECE1C35C1C600388446 /* ASRangeControllerBeta.h in Headers */,
|
||||||
254C6B7E1BF94DF4003EC431 /* ASTextKitTailTruncater.h in Headers */,
|
254C6B7E1BF94DF4003EC431 /* ASTextKitTailTruncater.h in Headers */,
|
||||||
B35062411B010EFD0018CF92 /* _ASAsyncTransactionGroup.h in Headers */,
|
B35062411B010EFD0018CF92 /* _ASAsyncTransactionGroup.h in Headers */,
|
||||||
B35062491B010EFD0018CF92 /* _ASCoreAnimationExtras.h in Headers */,
|
B35062491B010EFD0018CF92 /* _ASCoreAnimationExtras.h in Headers */,
|
||||||
@@ -1753,6 +1765,7 @@
|
|||||||
257754BE1BEE458E00737CA5 /* ASTextKitHelpers.mm in Sources */,
|
257754BE1BEE458E00737CA5 /* ASTextKitHelpers.mm in Sources */,
|
||||||
257754A91BEE44CD00737CA5 /* ASTextKitContext.mm in Sources */,
|
257754A91BEE44CD00737CA5 /* ASTextKitContext.mm in Sources */,
|
||||||
ACF6ED501B17847A00DA7C62 /* ASStackPositionedLayout.mm in Sources */,
|
ACF6ED501B17847A00DA7C62 /* ASStackPositionedLayout.mm in Sources */,
|
||||||
|
DECC2ECF1C35C1C600388446 /* ASRangeControllerBeta.mm in Sources */,
|
||||||
ACF6ED521B17847A00DA7C62 /* ASStackUnpositionedLayout.mm in Sources */,
|
ACF6ED521B17847A00DA7C62 /* ASStackUnpositionedLayout.mm in Sources */,
|
||||||
257754A61BEE44CD00737CA5 /* ASTextKitAttributes.mm in Sources */,
|
257754A61BEE44CD00737CA5 /* ASTextKitAttributes.mm in Sources */,
|
||||||
ACF6ED321B17843500DA7C62 /* ASStaticLayoutSpec.mm in Sources */,
|
ACF6ED321B17843500DA7C62 /* ASStaticLayoutSpec.mm in Sources */,
|
||||||
@@ -1883,6 +1896,7 @@
|
|||||||
9C8221981BA237B80037F19A /* ASStackBaselinePositionedLayout.mm in Sources */,
|
9C8221981BA237B80037F19A /* ASStackBaselinePositionedLayout.mm in Sources */,
|
||||||
34EFC7721B701D0300AD841F /* ASStackLayoutSpec.mm in Sources */,
|
34EFC7721B701D0300AD841F /* ASStackLayoutSpec.mm in Sources */,
|
||||||
34EFC7761B701D2A00AD841F /* ASStackPositionedLayout.mm in Sources */,
|
34EFC7761B701D2A00AD841F /* ASStackPositionedLayout.mm in Sources */,
|
||||||
|
DECC2ED01C35C1C600388446 /* ASRangeControllerBeta.mm in Sources */,
|
||||||
34EFC7781B701D3100AD841F /* ASStackUnpositionedLayout.mm in Sources */,
|
34EFC7781B701D3100AD841F /* ASStackUnpositionedLayout.mm in Sources */,
|
||||||
AC026B6C1BD57D6F00BBC17E /* ASChangeSetDataController.m in Sources */,
|
AC026B6C1BD57D6F00BBC17E /* ASChangeSetDataController.m in Sources */,
|
||||||
34EFC7741B701D0A00AD841F /* ASStaticLayoutSpec.mm in Sources */,
|
34EFC7741B701D0A00AD841F /* ASStaticLayoutSpec.mm in Sources */,
|
||||||
|
|||||||
@@ -14,6 +14,7 @@
|
|||||||
#import "ASCollectionViewLayoutController.h"
|
#import "ASCollectionViewLayoutController.h"
|
||||||
#import "ASCollectionViewFlowLayoutInspector.h"
|
#import "ASCollectionViewFlowLayoutInspector.h"
|
||||||
#import "ASDisplayNode+FrameworkPrivate.h"
|
#import "ASDisplayNode+FrameworkPrivate.h"
|
||||||
|
#import "ASDisplayNode+Beta.h"
|
||||||
#import "ASInternalHelpers.h"
|
#import "ASInternalHelpers.h"
|
||||||
#import "ASRangeController.h"
|
#import "ASRangeController.h"
|
||||||
#import "UICollectionViewLayout+ASConvenience.h"
|
#import "UICollectionViewLayout+ASConvenience.h"
|
||||||
@@ -150,9 +151,12 @@ static NSString * const kCellReuseIdentifier = @"_ASCollectionViewCell";
|
|||||||
self.strongCollectionNode = collectionNode;
|
self.strongCollectionNode = collectionNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
_layoutController = [[ASCollectionViewLayoutController alloc] initWithCollectionView:self];
|
_layoutController = [ASDisplayNode shouldUseNewRenderingRange] ?
|
||||||
|
[[ASCollectionViewLayoutControllerBeta alloc] initWithCollectionView:self] :
|
||||||
|
[[ASCollectionViewLayoutControllerStable alloc] initWithCollectionView:self];
|
||||||
|
|
||||||
_rangeController = [[ASRangeController alloc] init];
|
_rangeController = [ASDisplayNode shouldUseNewRenderingRange] ? [[ASRangeControllerBeta alloc] init]
|
||||||
|
: [[ASRangeControllerStable alloc] init];
|
||||||
_rangeController.dataSource = self;
|
_rangeController.dataSource = self;
|
||||||
_rangeController.delegate = self;
|
_rangeController.delegate = self;
|
||||||
_rangeController.layoutController = _layoutController;
|
_rangeController.layoutController = _layoutController;
|
||||||
@@ -319,22 +323,22 @@ static NSString * const kCellReuseIdentifier = @"_ASCollectionViewCell";
|
|||||||
|
|
||||||
- (void)setTuningParameters:(ASRangeTuningParameters)tuningParameters forRangeType:(ASLayoutRangeType)rangeType
|
- (void)setTuningParameters:(ASRangeTuningParameters)tuningParameters forRangeType:(ASLayoutRangeType)rangeType
|
||||||
{
|
{
|
||||||
[_layoutController setTuningParameters:tuningParameters forRangeType:rangeType];
|
[_rangeController setTuningParameters:tuningParameters forRangeType:rangeType];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (ASRangeTuningParameters)tuningParametersForRangeType:(ASLayoutRangeType)rangeType
|
- (ASRangeTuningParameters)tuningParametersForRangeType:(ASLayoutRangeType)rangeType
|
||||||
{
|
{
|
||||||
return [_layoutController tuningParametersForRangeType:rangeType];
|
return [_rangeController tuningParametersForRangeType:rangeType];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (ASRangeTuningParameters)rangeTuningParameters
|
- (ASRangeTuningParameters)rangeTuningParameters
|
||||||
{
|
{
|
||||||
return [self tuningParametersForRangeType:ASLayoutRangeTypeRender];
|
return [self tuningParametersForRangeType:ASLayoutRangeTypeDisplay];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)setRangeTuningParameters:(ASRangeTuningParameters)tuningParameters
|
- (void)setRangeTuningParameters:(ASRangeTuningParameters)tuningParameters
|
||||||
{
|
{
|
||||||
[self setTuningParameters:tuningParameters forRangeType:ASLayoutRangeTypeRender];
|
[self setTuningParameters:tuningParameters forRangeType:ASLayoutRangeTypeDisplay];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (CGSize)calculatedSizeForNodeAtIndexPath:(NSIndexPath *)indexPath
|
- (CGSize)calculatedSizeForNodeAtIndexPath:(NSIndexPath *)indexPath
|
||||||
@@ -775,6 +779,11 @@ static NSString * const kCellReuseIdentifier = @"_ASCollectionViewCell";
|
|||||||
return [_dataController nodesAtIndexPaths:indexPaths];
|
return [_dataController nodesAtIndexPaths:indexPaths];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (ASDisplayNode *)rangeController:(ASRangeController *)rangeController nodeAtIndexPath:(NSIndexPath *)indexPath
|
||||||
|
{
|
||||||
|
return [_dataController nodeAtIndexPath:indexPath];
|
||||||
|
}
|
||||||
|
|
||||||
#pragma mark - ASRangeControllerDelegate
|
#pragma mark - ASRangeControllerDelegate
|
||||||
|
|
||||||
- (void)didBeginUpdatesInRangeController:(ASRangeController *)rangeController
|
- (void)didBeginUpdatesInRangeController:(ASRangeController *)rangeController
|
||||||
|
|||||||
@@ -203,20 +203,26 @@ static ASDisplayNodeMethodOverrides GetASDisplayNodeMethodOverrides(Class c)
|
|||||||
ASDisplayNodeAssertMainThread();
|
ASDisplayNodeAssertMainThread();
|
||||||
static NSMutableSet *nodesToDisplay = nil;
|
static NSMutableSet *nodesToDisplay = nil;
|
||||||
static BOOL displayScheduled = NO;
|
static BOOL displayScheduled = NO;
|
||||||
|
static ASDN::RecursiveMutex displaySchedulerLock;
|
||||||
|
{
|
||||||
|
ASDN::MutexLocker l(displaySchedulerLock);
|
||||||
if (!nodesToDisplay) {
|
if (!nodesToDisplay) {
|
||||||
nodesToDisplay = [[NSMutableSet alloc] init];
|
nodesToDisplay = [[NSMutableSet alloc] init];
|
||||||
}
|
}
|
||||||
[nodesToDisplay addObject:node];
|
[nodesToDisplay addObject:node];
|
||||||
|
}
|
||||||
if (!displayScheduled) {
|
if (!displayScheduled) {
|
||||||
displayScheduled = YES;
|
displayScheduled = YES;
|
||||||
// It's essenital that any layout pass that is scheduled during the current
|
// It's essenital that any layout pass that is scheduled during the current
|
||||||
// runloop has a chance to be applied / scheduled, so always perform this after the current runloop.
|
// runloop has a chance to be applied / scheduled, so always perform this after the current runloop.
|
||||||
dispatch_async(dispatch_get_main_queue(), ^{
|
dispatch_async(dispatch_get_main_queue(), ^{
|
||||||
|
ASDN::MutexLocker l(displaySchedulerLock);
|
||||||
displayScheduled = NO;
|
displayScheduled = NO;
|
||||||
for (ASDisplayNode *node in nodesToDisplay) {
|
NSSet *displayingNodes = [nodesToDisplay copy];
|
||||||
|
nodesToDisplay = nil;
|
||||||
|
for (ASDisplayNode *node in displayingNodes) {
|
||||||
[node __recursivelyTriggerDisplayAndBlock:NO];
|
[node __recursivelyTriggerDisplayAndBlock:NO];
|
||||||
}
|
}
|
||||||
nodesToDisplay = nil;
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1835,6 +1841,15 @@ static BOOL ShouldUseNewRenderingRange = NO;
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)recursivelySetInterfaceState:(ASInterfaceState)interfaceState
|
||||||
|
{
|
||||||
|
ASDisplayNodePerformBlockOnEveryNode(nil, self, ^(ASDisplayNode *node) {
|
||||||
|
node.interfaceState = interfaceState;
|
||||||
|
});
|
||||||
|
// FIXME: This should also be called in setInterfaceState: if it isn't being applied recursively.
|
||||||
|
[ASDisplayNode scheduleNodeForDisplay:self];
|
||||||
|
}
|
||||||
|
|
||||||
- (ASHierarchyState)hierarchyState
|
- (ASHierarchyState)hierarchyState
|
||||||
{
|
{
|
||||||
ASDN::MutexLocker l(_propertyLock);
|
ASDN::MutexLocker l(_propertyLock);
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
#import "ASPagerNode.h"
|
#import "ASPagerNode.h"
|
||||||
#import "ASDelegateProxy.h"
|
#import "ASDelegateProxy.h"
|
||||||
#import "ASDisplayNode+Subclasses.h"
|
#import "ASDisplayNode+Subclasses.h"
|
||||||
|
#import "UICollectionViewLayout+ASConvenience.h"
|
||||||
|
|
||||||
@interface ASPagerNode () <ASCollectionDataSource, ASCollectionViewDelegateFlowLayout, ASDelegateProxyInterceptor>
|
@interface ASPagerNode () <ASCollectionDataSource, ASCollectionViewDelegateFlowLayout, ASDelegateProxyInterceptor>
|
||||||
{
|
{
|
||||||
@@ -34,7 +35,7 @@
|
|||||||
|
|
||||||
- (instancetype)initWithCollectionViewLayout:(UICollectionViewFlowLayout *)flowLayout;
|
- (instancetype)initWithCollectionViewLayout:(UICollectionViewFlowLayout *)flowLayout;
|
||||||
{
|
{
|
||||||
ASDisplayNodeAssert([flowLayout isKindOfClass:[UICollectionViewFlowLayout class]], @"ASPagerNode requires a flow layout.");
|
ASDisplayNodeAssert([flowLayout asdk_isFlowLayout], @"ASPagerNode requires a flow layout.");
|
||||||
self = [super initWithCollectionViewLayout:flowLayout];
|
self = [super initWithCollectionViewLayout:flowLayout];
|
||||||
if (self != nil) {
|
if (self != nil) {
|
||||||
_flowLayout = flowLayout;
|
_flowLayout = flowLayout;
|
||||||
@@ -61,8 +62,8 @@
|
|||||||
|
|
||||||
ASRangeTuningParameters preloadParams = { .leadingBufferScreenfuls = 2.0, .trailingBufferScreenfuls = 2.0 };
|
ASRangeTuningParameters preloadParams = { .leadingBufferScreenfuls = 2.0, .trailingBufferScreenfuls = 2.0 };
|
||||||
ASRangeTuningParameters renderParams = { .leadingBufferScreenfuls = 1.0, .trailingBufferScreenfuls = 1.0 };
|
ASRangeTuningParameters renderParams = { .leadingBufferScreenfuls = 1.0, .trailingBufferScreenfuls = 1.0 };
|
||||||
[self setTuningParameters:preloadParams forRangeType:ASLayoutRangeTypePreload];
|
[self setTuningParameters:preloadParams forRangeType:ASLayoutRangeTypeFetchData];
|
||||||
[self setTuningParameters:renderParams forRangeType:ASLayoutRangeTypeRender];
|
[self setTuningParameters:renderParams forRangeType:ASLayoutRangeTypeDisplay];
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma mark - Helpers
|
#pragma mark - Helpers
|
||||||
|
|||||||
@@ -13,6 +13,7 @@
|
|||||||
#import "ASChangeSetDataController.h"
|
#import "ASChangeSetDataController.h"
|
||||||
#import "ASCollectionViewLayoutController.h"
|
#import "ASCollectionViewLayoutController.h"
|
||||||
#import "ASDelegateProxy.h"
|
#import "ASDelegateProxy.h"
|
||||||
|
#import "ASDisplayNode+Beta.h"
|
||||||
#import "ASDisplayNode+FrameworkPrivate.h"
|
#import "ASDisplayNode+FrameworkPrivate.h"
|
||||||
#import "ASInternalHelpers.h"
|
#import "ASInternalHelpers.h"
|
||||||
#import "ASLayout.h"
|
#import "ASLayout.h"
|
||||||
@@ -85,7 +86,10 @@ static NSString * const kCellReuseIdentifier = @"_ASTableViewCell";
|
|||||||
- (instancetype)_initWithTableView:(ASTableView *)tableView;
|
- (instancetype)_initWithTableView:(ASTableView *)tableView;
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@interface ASTableView () <ASRangeControllerDataSource, ASRangeControllerDelegate, ASDataControllerSource, _ASTableViewCellDelegate, ASCellNodeLayoutDelegate, ASDelegateProxyInterceptor> {
|
@interface ASTableView () <ASRangeControllerDataSource, ASRangeControllerDelegate,
|
||||||
|
ASDataControllerSource, _ASTableViewCellDelegate,
|
||||||
|
ASCellNodeLayoutDelegate, ASDelegateProxyInterceptor>
|
||||||
|
{
|
||||||
ASTableViewProxy *_proxyDataSource;
|
ASTableViewProxy *_proxyDataSource;
|
||||||
ASTableViewProxy *_proxyDelegate;
|
ASTableViewProxy *_proxyDelegate;
|
||||||
|
|
||||||
@@ -139,7 +143,8 @@ static NSString * const kCellReuseIdentifier = @"_ASTableViewCell";
|
|||||||
{
|
{
|
||||||
_layoutController = [[ASFlowLayoutController alloc] initWithScrollOption:ASFlowLayoutDirectionVertical];
|
_layoutController = [[ASFlowLayoutController alloc] initWithScrollOption:ASFlowLayoutDirectionVertical];
|
||||||
|
|
||||||
_rangeController = [[ASRangeController alloc] init];
|
_rangeController = [ASDisplayNode shouldUseNewRenderingRange] ? [[ASRangeControllerBeta alloc] init]
|
||||||
|
: [[ASRangeControllerStable alloc] init];
|
||||||
_rangeController.layoutController = _layoutController;
|
_rangeController.layoutController = _layoutController;
|
||||||
_rangeController.dataSource = self;
|
_rangeController.dataSource = self;
|
||||||
_rangeController.delegate = self;
|
_rangeController.delegate = self;
|
||||||
@@ -317,12 +322,12 @@ static NSString * const kCellReuseIdentifier = @"_ASTableViewCell";
|
|||||||
|
|
||||||
- (ASRangeTuningParameters)rangeTuningParameters
|
- (ASRangeTuningParameters)rangeTuningParameters
|
||||||
{
|
{
|
||||||
return [self tuningParametersForRangeType:ASLayoutRangeTypeRender];
|
return [self tuningParametersForRangeType:ASLayoutRangeTypeDisplay];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)setRangeTuningParameters:(ASRangeTuningParameters)tuningParameters
|
- (void)setRangeTuningParameters:(ASRangeTuningParameters)tuningParameters
|
||||||
{
|
{
|
||||||
[self setTuningParameters:tuningParameters forRangeType:ASLayoutRangeTypeRender];
|
[self setTuningParameters:tuningParameters forRangeType:ASLayoutRangeTypeDisplay];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (ASCellNode *)nodeForRowAtIndexPath:(NSIndexPath *)indexPath
|
- (ASCellNode *)nodeForRowAtIndexPath:(NSIndexPath *)indexPath
|
||||||
@@ -684,6 +689,11 @@ static NSString * const kCellReuseIdentifier = @"_ASTableViewCell";
|
|||||||
return [_dataController nodesAtIndexPaths:indexPaths];
|
return [_dataController nodesAtIndexPaths:indexPaths];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (ASDisplayNode *)rangeController:(ASRangeController *)rangeController nodeAtIndexPath:(NSIndexPath *)indexPath
|
||||||
|
{
|
||||||
|
return [_dataController nodeAtIndexPath:indexPath];
|
||||||
|
}
|
||||||
|
|
||||||
- (CGSize)viewportSizeForRangeController:(ASRangeController *)rangeController
|
- (CGSize)viewportSizeForRangeController:(ASRangeController *)rangeController
|
||||||
{
|
{
|
||||||
ASDisplayNodeAssertMainThread();
|
ASDisplayNodeAssertMainThread();
|
||||||
|
|||||||
@@ -13,10 +13,6 @@ NS_ASSUME_NONNULL_BEGIN
|
|||||||
|
|
||||||
@interface ASAbstractLayoutController : NSObject <ASLayoutController>
|
@interface ASAbstractLayoutController : NSObject <ASLayoutController>
|
||||||
|
|
||||||
- (void)setTuningParameters:(ASRangeTuningParameters)tuningParameters forRangeType:(ASLayoutRangeType)rangeType;
|
|
||||||
|
|
||||||
- (ASRangeTuningParameters)tuningParametersForRangeType:(ASLayoutRangeType)rangeType;
|
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
NS_ASSUME_NONNULL_END
|
NS_ASSUME_NONNULL_END
|
||||||
|
|||||||
@@ -14,6 +14,7 @@
|
|||||||
|
|
||||||
@interface ASAbstractLayoutController () {
|
@interface ASAbstractLayoutController () {
|
||||||
std::vector<ASRangeTuningParameters> _tuningParameters;
|
std::vector<ASRangeTuningParameters> _tuningParameters;
|
||||||
|
CGSize _viewportSize;
|
||||||
}
|
}
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@@ -30,11 +31,11 @@
|
|||||||
.leadingBufferScreenfuls = 0,
|
.leadingBufferScreenfuls = 0,
|
||||||
.trailingBufferScreenfuls = 0
|
.trailingBufferScreenfuls = 0
|
||||||
};
|
};
|
||||||
_tuningParameters[ASLayoutRangeTypeRender] = {
|
_tuningParameters[ASLayoutRangeTypeDisplay] = {
|
||||||
.leadingBufferScreenfuls = 1.5,
|
.leadingBufferScreenfuls = 1.5,
|
||||||
.trailingBufferScreenfuls = 0.75
|
.trailingBufferScreenfuls = 0.75
|
||||||
};
|
};
|
||||||
_tuningParameters[ASLayoutRangeTypePreload] = {
|
_tuningParameters[ASLayoutRangeTypeFetchData] = {
|
||||||
.leadingBufferScreenfuls = 3,
|
.leadingBufferScreenfuls = 3,
|
||||||
.trailingBufferScreenfuls = 2
|
.trailingBufferScreenfuls = 2
|
||||||
};
|
};
|
||||||
@@ -60,16 +61,27 @@
|
|||||||
|
|
||||||
#pragma mark - Abstract Index Path Range Support
|
#pragma mark - Abstract Index Path Range Support
|
||||||
|
|
||||||
- (BOOL)shouldUpdateForVisibleIndexPaths:(NSArray *)indexPaths viewportSize:(CGSize)viewportSize rangeType:(ASLayoutRangeType)rangeType
|
// FIXME: This method can be removed once ASRangeControllerBeta becomes the main version.
|
||||||
|
- (BOOL)shouldUpdateForVisibleIndexPaths:(NSArray *)indexPaths rangeType:(ASLayoutRangeType)rangeType
|
||||||
{
|
{
|
||||||
ASDisplayNodeAssertNotSupported();
|
ASDisplayNodeAssertNotSupported();
|
||||||
return NO;
|
return NO;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSSet *)indexPathsForScrolling:(ASScrollDirection)scrollDirection viewportSize:(CGSize)viewportSize rangeType:(ASLayoutRangeType)rangeType
|
- (NSSet *)indexPathsForScrolling:(ASScrollDirection)scrollDirection rangeType:(ASLayoutRangeType)rangeType
|
||||||
{
|
{
|
||||||
ASDisplayNodeAssertNotSupported();
|
ASDisplayNodeAssertNotSupported();
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)setViewportSize:(CGSize)viewportSize
|
||||||
|
{
|
||||||
|
_viewportSize = viewportSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (CGSize)viewportSize
|
||||||
|
{
|
||||||
|
return _viewportSize;
|
||||||
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|||||||
@@ -19,4 +19,10 @@ NS_ASSUME_NONNULL_BEGIN
|
|||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
@interface ASCollectionViewLayoutControllerStable : ASCollectionViewLayoutController
|
||||||
|
@end
|
||||||
|
|
||||||
|
@interface ASCollectionViewLayoutControllerBeta : ASCollectionViewLayoutController
|
||||||
|
@end
|
||||||
|
|
||||||
NS_ASSUME_NONNULL_END
|
NS_ASSUME_NONNULL_END
|
||||||
|
|||||||
@@ -15,36 +15,6 @@
|
|||||||
#import "CGRect+ASConvenience.h"
|
#import "CGRect+ASConvenience.h"
|
||||||
#import "UICollectionViewLayout+ASConvenience.h"
|
#import "UICollectionViewLayout+ASConvenience.h"
|
||||||
|
|
||||||
struct ASDirectionalScreenfulBuffer {
|
|
||||||
CGFloat positiveDirection; // Positive relative to iOS Core Animation layer coordinate space.
|
|
||||||
CGFloat negativeDirection;
|
|
||||||
};
|
|
||||||
typedef struct ASDirectionalScreenfulBuffer ASDirectionalScreenfulBuffer;
|
|
||||||
|
|
||||||
ASDirectionalScreenfulBuffer ASDirectionalScreenfulBufferHorizontal(ASScrollDirection scrollDirection,
|
|
||||||
ASRangeTuningParameters rangeTuningParameters)
|
|
||||||
{
|
|
||||||
ASDirectionalScreenfulBuffer horizontalBuffer = {0, 0};
|
|
||||||
BOOL movingRight = ASScrollDirectionContainsRight(scrollDirection);
|
|
||||||
horizontalBuffer.positiveDirection = movingRight ? rangeTuningParameters.leadingBufferScreenfuls :
|
|
||||||
rangeTuningParameters.trailingBufferScreenfuls;
|
|
||||||
horizontalBuffer.negativeDirection = movingRight ? rangeTuningParameters.trailingBufferScreenfuls :
|
|
||||||
rangeTuningParameters.leadingBufferScreenfuls;
|
|
||||||
return horizontalBuffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
ASDirectionalScreenfulBuffer ASDirectionalScreenfulBufferVertical(ASScrollDirection scrollDirection,
|
|
||||||
ASRangeTuningParameters rangeTuningParameters)
|
|
||||||
{
|
|
||||||
ASDirectionalScreenfulBuffer verticalBuffer = {0, 0};
|
|
||||||
BOOL movingDown = ASScrollDirectionContainsDown(scrollDirection);
|
|
||||||
verticalBuffer.positiveDirection = movingDown ? rangeTuningParameters.leadingBufferScreenfuls :
|
|
||||||
rangeTuningParameters.trailingBufferScreenfuls;
|
|
||||||
verticalBuffer.negativeDirection = movingDown ? rangeTuningParameters.trailingBufferScreenfuls :
|
|
||||||
rangeTuningParameters.leadingBufferScreenfuls;
|
|
||||||
return verticalBuffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct ASRangeGeometry {
|
struct ASRangeGeometry {
|
||||||
CGRect rangeBounds;
|
CGRect rangeBounds;
|
||||||
CGRect updateBounds;
|
CGRect updateBounds;
|
||||||
@@ -57,9 +27,9 @@ typedef struct ASRangeGeometry ASRangeGeometry;
|
|||||||
|
|
||||||
@interface ASCollectionViewLayoutController ()
|
@interface ASCollectionViewLayoutController ()
|
||||||
{
|
{
|
||||||
|
@package
|
||||||
ASCollectionView * __weak _collectionView;
|
ASCollectionView * __weak _collectionView;
|
||||||
UICollectionViewLayout * __strong _collectionViewLayout;
|
UICollectionViewLayout * __strong _collectionViewLayout;
|
||||||
std::vector<CGRect> _updateRangeBoundsIndexedByRangeType;
|
|
||||||
ASScrollDirection _scrollableDirections;
|
ASScrollDirection _scrollableDirections;
|
||||||
}
|
}
|
||||||
@end
|
@end
|
||||||
@@ -75,63 +45,34 @@ typedef struct ASRangeGeometry ASRangeGeometry;
|
|||||||
_scrollableDirections = [collectionView scrollableDirections];
|
_scrollableDirections = [collectionView scrollableDirections];
|
||||||
_collectionView = collectionView;
|
_collectionView = collectionView;
|
||||||
_collectionViewLayout = [collectionView collectionViewLayout];
|
_collectionViewLayout = [collectionView collectionViewLayout];
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation ASCollectionViewLayoutControllerStable
|
||||||
|
{
|
||||||
|
std::vector<CGRect> _updateRangeBoundsIndexedByRangeType;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (instancetype)initWithCollectionView:(ASCollectionView *)collectionView
|
||||||
|
{
|
||||||
|
if (!(self = [super initWithCollectionView:collectionView])) {
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
_updateRangeBoundsIndexedByRangeType = std::vector<CGRect>(ASLayoutRangeTypeCount);
|
_updateRangeBoundsIndexedByRangeType = std::vector<CGRect>(ASLayoutRangeTypeCount);
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma mark -
|
- (NSSet *)indexPathsForScrolling:(ASScrollDirection)scrollDirection rangeType:(ASLayoutRangeType)rangeType
|
||||||
#pragma mark Index Paths in Range
|
|
||||||
|
|
||||||
- (NSSet *)indexPathsForScrolling:(ASScrollDirection)scrollDirection
|
|
||||||
viewportSize:(CGSize)viewportSize
|
|
||||||
rangeType:(ASLayoutRangeType)rangeType
|
|
||||||
{
|
{
|
||||||
ASRangeGeometry rangeGeometry = [self rangeGeometryWithScrollDirection:scrollDirection
|
ASRangeTuningParameters tuningParameters = [self tuningParametersForRangeType:rangeType];
|
||||||
rangeTuningParameters:[self tuningParametersForRangeType:rangeType]];
|
ASRangeGeometry rangeGeometry = [self rangeGeometryWithScrollDirection:scrollDirection tuningParameters:tuningParameters];
|
||||||
_updateRangeBoundsIndexedByRangeType[rangeType] = rangeGeometry.updateBounds;
|
_updateRangeBoundsIndexedByRangeType[rangeType] = rangeGeometry.updateBounds;
|
||||||
return [self indexPathsForItemsWithinRangeBounds:rangeGeometry.rangeBounds];
|
return [self indexPathsForItemsWithinRangeBounds:rangeGeometry.rangeBounds];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (ASRangeGeometry)rangeGeometryWithScrollDirection:(ASScrollDirection)scrollDirection
|
|
||||||
rangeTuningParameters:(ASRangeTuningParameters)rangeTuningParameters
|
|
||||||
{
|
|
||||||
CGRect rangeBounds = _collectionView.bounds;
|
|
||||||
CGRect updateBounds = _collectionView.bounds;
|
|
||||||
|
|
||||||
//scrollable directions can change for non-flow layouts
|
|
||||||
if ([_collectionViewLayout asdk_isFlowLayout] == NO) {
|
|
||||||
_scrollableDirections = [_collectionView scrollableDirections];
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOL canScrollHorizontally = ASScrollDirectionContainsHorizontalDirection(_scrollableDirections);
|
|
||||||
if (canScrollHorizontally) {
|
|
||||||
ASDirectionalScreenfulBuffer horizontalBuffer = ASDirectionalScreenfulBufferHorizontal(scrollDirection,
|
|
||||||
rangeTuningParameters);
|
|
||||||
rangeBounds = asdk_CGRectExpandHorizontally(rangeBounds,
|
|
||||||
horizontalBuffer.negativeDirection,
|
|
||||||
horizontalBuffer.positiveDirection);
|
|
||||||
// Update bounds is at most 95% of the next/previous screenful and at least half of tuning parameter value.
|
|
||||||
updateBounds = asdk_CGRectExpandHorizontally(updateBounds,
|
|
||||||
MIN(horizontalBuffer.negativeDirection * 0.5, 0.95),
|
|
||||||
MIN(horizontalBuffer.positiveDirection * 0.5, 0.95));
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOL canScrollVertically = ASScrollDirectionContainsVerticalDirection(_scrollableDirections);
|
|
||||||
if (canScrollVertically) {
|
|
||||||
ASDirectionalScreenfulBuffer verticalBuffer = ASDirectionalScreenfulBufferVertical(scrollDirection,
|
|
||||||
rangeTuningParameters);
|
|
||||||
rangeBounds = asdk_CGRectExpandVertically(rangeBounds,
|
|
||||||
verticalBuffer.negativeDirection,
|
|
||||||
verticalBuffer.positiveDirection);
|
|
||||||
// Update bounds is at most 95% of the next/previous screenful and at least half of tuning parameter value.
|
|
||||||
updateBounds = asdk_CGRectExpandVertically(updateBounds,
|
|
||||||
MIN(verticalBuffer.negativeDirection * 0.5, 0.95),
|
|
||||||
MIN(verticalBuffer.positiveDirection * 0.5, 0.95));
|
|
||||||
}
|
|
||||||
|
|
||||||
return {rangeBounds, updateBounds};
|
|
||||||
}
|
|
||||||
|
|
||||||
- (NSSet *)indexPathsForItemsWithinRangeBounds:(CGRect)rangeBounds
|
- (NSSet *)indexPathsForItemsWithinRangeBounds:(CGRect)rangeBounds
|
||||||
{
|
{
|
||||||
NSMutableSet *indexPathSet = [[NSMutableSet alloc] init];
|
NSMutableSet *indexPathSet = [[NSMutableSet alloc] init];
|
||||||
@@ -144,13 +85,31 @@ typedef struct ASRangeGeometry ASRangeGeometry;
|
|||||||
return indexPathSet;
|
return indexPathSet;
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma mark -
|
- (ASRangeGeometry)rangeGeometryWithScrollDirection:(ASScrollDirection)scrollDirection
|
||||||
#pragma mark Should Update Range
|
tuningParameters:(ASRangeTuningParameters)tuningParameters
|
||||||
|
|
||||||
- (BOOL)shouldUpdateForVisibleIndexPaths:(NSArray *)indexPaths
|
|
||||||
viewportSize:(CGSize)viewportSize
|
|
||||||
rangeType:(ASLayoutRangeType)rangeType
|
|
||||||
{
|
{
|
||||||
|
CGRect rangeBounds = _collectionView.bounds;
|
||||||
|
CGRect updateBounds = _collectionView.bounds;
|
||||||
|
|
||||||
|
// Scrollable directions can change for non-flow layouts
|
||||||
|
if ([_collectionViewLayout asdk_isFlowLayout] == NO) {
|
||||||
|
_scrollableDirections = [_collectionView scrollableDirections];
|
||||||
|
}
|
||||||
|
|
||||||
|
rangeBounds = CGRectExpandToRangeWithScrollableDirections(rangeBounds, tuningParameters, _scrollableDirections, scrollDirection);
|
||||||
|
|
||||||
|
ASRangeTuningParameters updateTuningParameters = tuningParameters;
|
||||||
|
updateTuningParameters.leadingBufferScreenfuls = MIN(updateTuningParameters.leadingBufferScreenfuls * 0.5, 0.95);
|
||||||
|
updateTuningParameters.trailingBufferScreenfuls = MIN(updateTuningParameters.trailingBufferScreenfuls * 0.5, 0.95);
|
||||||
|
|
||||||
|
updateBounds = CGRectExpandToRangeWithScrollableDirections(updateBounds, updateTuningParameters, _scrollableDirections, scrollDirection);
|
||||||
|
|
||||||
|
return {rangeBounds, updateBounds};
|
||||||
|
}
|
||||||
|
|
||||||
|
- (BOOL)shouldUpdateForVisibleIndexPaths:(NSArray *)indexPaths rangeType:(ASLayoutRangeType)rangeType
|
||||||
|
{
|
||||||
|
CGSize viewportSize = [self viewportSize];
|
||||||
CGRect updateRangeBounds = _updateRangeBoundsIndexedByRangeType[rangeType];
|
CGRect updateRangeBounds = _updateRangeBoundsIndexedByRangeType[rangeType];
|
||||||
if (CGRectIsEmpty(updateRangeBounds)) {
|
if (CGRectIsEmpty(updateRangeBounds)) {
|
||||||
return YES;
|
return YES;
|
||||||
@@ -169,3 +128,40 @@ typedef struct ASRangeGeometry ASRangeGeometry;
|
|||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
|
||||||
|
@implementation ASCollectionViewLayoutControllerBeta
|
||||||
|
|
||||||
|
- (NSSet *)indexPathsForScrolling:(ASScrollDirection)scrollDirection rangeType:(ASLayoutRangeType)rangeType
|
||||||
|
{
|
||||||
|
ASRangeTuningParameters tuningParameters = [self tuningParametersForRangeType:rangeType];
|
||||||
|
CGRect rangeBounds = [self rangeBoundsWithScrollDirection:scrollDirection rangeTuningParameters:tuningParameters];
|
||||||
|
return [self indexPathsForItemsWithinRangeBounds:rangeBounds];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSSet *)indexPathsForItemsWithinRangeBounds:(CGRect)rangeBounds
|
||||||
|
{
|
||||||
|
NSArray *layoutAttributes = [_collectionViewLayout layoutAttributesForElementsInRect:rangeBounds];
|
||||||
|
NSMutableSet *indexPathSet = [NSMutableSet setWithCapacity:layoutAttributes.count];
|
||||||
|
for (UICollectionViewLayoutAttributes *la in layoutAttributes) {
|
||||||
|
//ASDisplayNodeAssert(![indexPathSet containsObject:la.indexPath], @"Shouldn't already contain indexPath");
|
||||||
|
ASDisplayNodeAssert(la.representedElementCategory != UICollectionElementCategoryDecorationView, @"UICollectionView decoration views are not supported by ASCollectionView");
|
||||||
|
[indexPathSet addObject:la.indexPath];
|
||||||
|
}
|
||||||
|
return indexPathSet;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (CGRect)rangeBoundsWithScrollDirection:(ASScrollDirection)scrollDirection
|
||||||
|
rangeTuningParameters:(ASRangeTuningParameters)tuningParameters
|
||||||
|
{
|
||||||
|
CGRect rect = _collectionView.bounds;
|
||||||
|
|
||||||
|
// Scrollable directions can change for non-flow layouts
|
||||||
|
if ([_collectionViewLayout asdk_isFlowLayout] == NO) {
|
||||||
|
_scrollableDirections = [_collectionView scrollableDirections];
|
||||||
|
}
|
||||||
|
|
||||||
|
return CGRectExpandToRangeWithScrollableDirections(rect, tuningParameters, _scrollableDirections, scrollDirection);
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
|
|||||||
@@ -39,7 +39,8 @@ static const CGFloat kASFlowLayoutControllerRefreshingThreshold = 0.3;
|
|||||||
|
|
||||||
#pragma mark - Visible Indices
|
#pragma mark - Visible Indices
|
||||||
|
|
||||||
- (BOOL)shouldUpdateForVisibleIndexPaths:(NSArray *)indexPaths viewportSize:(CGSize)viewportSize rangeType:(ASLayoutRangeType)rangeType
|
// FIXME: This method can be removed once ASRangeControllerBeta becomes the main version.
|
||||||
|
- (BOOL)shouldUpdateForVisibleIndexPaths:(NSArray *)indexPaths rangeType:(ASLayoutRangeType)rangeType
|
||||||
{
|
{
|
||||||
if (!indexPaths.count || rangeType >= _rangesByType.size()) {
|
if (!indexPaths.count || rangeType >= _rangesByType.size()) {
|
||||||
return NO;
|
return NO;
|
||||||
@@ -73,10 +74,11 @@ static const CGFloat kASFlowLayoutControllerRefreshingThreshold = 0.3;
|
|||||||
* IndexPath array for the element in the working range.
|
* IndexPath array for the element in the working range.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
- (NSSet *)indexPathsForScrolling:(ASScrollDirection)scrollDirection viewportSize:(CGSize)viewportSize rangeType:(ASLayoutRangeType)rangeType
|
- (NSSet *)indexPathsForScrolling:(ASScrollDirection)scrollDirection rangeType:(ASLayoutRangeType)rangeType
|
||||||
{
|
{
|
||||||
CGFloat viewportScreenMetric;
|
CGFloat viewportScreenMetric;
|
||||||
ASScrollDirection leadingDirection;
|
ASScrollDirection leadingDirection;
|
||||||
|
CGSize viewportSize = [self viewportSize];
|
||||||
|
|
||||||
if (_layoutDirection == ASFlowLayoutDirectionHorizontal) {
|
if (_layoutDirection == ASFlowLayoutDirectionHorizontal) {
|
||||||
ASDisplayNodeAssert(scrollDirection == ASScrollDirectionNone || scrollDirection == ASScrollDirectionLeft || scrollDirection == ASScrollDirectionRight, @"Invalid scroll direction");
|
ASDisplayNodeAssert(scrollDirection == ASScrollDirectionNone || scrollDirection == ASScrollDirectionLeft || scrollDirection == ASScrollDirectionRight, @"Invalid scroll direction");
|
||||||
|
|||||||
@@ -28,11 +28,14 @@ typedef struct {
|
|||||||
*
|
*
|
||||||
* Defaults to a trailing buffer of one screenful and a leading buffer of two screenfuls.
|
* Defaults to a trailing buffer of one screenful and a leading buffer of two screenfuls.
|
||||||
*/
|
*/
|
||||||
|
- (void)setTuningParameters:(ASRangeTuningParameters)tuningParameters forRangeType:(ASLayoutRangeType)rangeType;
|
||||||
|
|
||||||
- (ASRangeTuningParameters)tuningParametersForRangeType:(ASLayoutRangeType)rangeType;
|
- (ASRangeTuningParameters)tuningParametersForRangeType:(ASLayoutRangeType)rangeType;
|
||||||
|
|
||||||
- (BOOL)shouldUpdateForVisibleIndexPaths:(NSArray<NSIndexPath *> *)indexPaths viewportSize:(CGSize)viewportSize rangeType:(ASLayoutRangeType)rangeType;
|
// FIXME: This method can be removed once ASRangeControllerBeta becomes the main version.
|
||||||
|
- (BOOL)shouldUpdateForVisibleIndexPaths:(NSArray<NSIndexPath *> *)indexPaths rangeType:(ASLayoutRangeType)rangeType;
|
||||||
|
|
||||||
- (NSSet *)indexPathsForScrolling:(ASScrollDirection)scrollDirection viewportSize:(CGSize)viewportSize rangeType:(ASLayoutRangeType)rangeType;
|
- (NSSet *)indexPathsForScrolling:(ASScrollDirection)scrollDirection rangeType:(ASLayoutRangeType)rangeType;
|
||||||
|
|
||||||
@optional
|
@optional
|
||||||
|
|
||||||
@@ -46,6 +49,9 @@ typedef struct {
|
|||||||
|
|
||||||
- (void)setVisibleNodeIndexPaths:(NSArray<NSIndexPath *> *)indexPaths;
|
- (void)setVisibleNodeIndexPaths:(NSArray<NSIndexPath *> *)indexPaths;
|
||||||
|
|
||||||
|
- (void)setViewportSize:(CGSize)viewportSize;
|
||||||
|
- (CGSize)viewportSize;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
NS_ASSUME_NONNULL_END
|
NS_ASSUME_NONNULL_END
|
||||||
|
|||||||
@@ -10,7 +10,10 @@
|
|||||||
|
|
||||||
typedef NS_ENUM(NSInteger, ASLayoutRangeType) {
|
typedef NS_ENUM(NSInteger, ASLayoutRangeType) {
|
||||||
ASLayoutRangeTypeVisible = 0,
|
ASLayoutRangeTypeVisible = 0,
|
||||||
ASLayoutRangeTypeRender,
|
ASLayoutRangeTypeDisplay,
|
||||||
ASLayoutRangeTypePreload,
|
ASLayoutRangeTypeFetchData,
|
||||||
ASLayoutRangeTypeCount
|
ASLayoutRangeTypeCount
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define ASLayoutRangeTypeRender ASLayoutRangeTypeDisplay
|
||||||
|
#define ASLayoutRangeTypePreload ASLayoutRangeTypeFetchData
|
||||||
|
|||||||
@@ -26,6 +26,11 @@ NS_ASSUME_NONNULL_BEGIN
|
|||||||
* This includes cancelling those asynchronous operations as cells fall outside of the working ranges.
|
* This includes cancelling those asynchronous operations as cells fall outside of the working ranges.
|
||||||
*/
|
*/
|
||||||
@interface ASRangeController : ASDealloc2MainObject <ASDataControllerDelegate>
|
@interface ASRangeController : ASDealloc2MainObject <ASDataControllerDelegate>
|
||||||
|
{
|
||||||
|
id<ASLayoutController> _layoutController;
|
||||||
|
__weak id<ASRangeControllerDataSource> _dataSource;
|
||||||
|
__weak id<ASRangeControllerDelegate> _delegate;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Notify the range controller that the visible range has been updated.
|
* Notify the range controller that the visible range has been updated.
|
||||||
@@ -46,6 +51,9 @@ NS_ASSUME_NONNULL_BEGIN
|
|||||||
*/
|
*/
|
||||||
- (void)configureContentView:(UIView *)contentView forCellNode:(ASCellNode *)node;
|
- (void)configureContentView:(UIView *)contentView forCellNode:(ASCellNode *)node;
|
||||||
|
|
||||||
|
- (void)setTuningParameters:(ASRangeTuningParameters)tuningParameters forRangeType:(ASLayoutRangeType)rangeType;
|
||||||
|
- (ASRangeTuningParameters)tuningParametersForRangeType:(ASLayoutRangeType)rangeType;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An object that describes the layout behavior of the ranged component (table view, collection view, etc.)
|
* An object that describes the layout behavior of the ranged component (table view, collection view, etc.)
|
||||||
*
|
*
|
||||||
@@ -66,6 +74,12 @@ NS_ASSUME_NONNULL_BEGIN
|
|||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
@interface ASRangeControllerStable : ASRangeController
|
||||||
|
@end
|
||||||
|
|
||||||
|
@interface ASRangeControllerBeta : ASRangeController
|
||||||
|
@end
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Data source for ASRangeController.
|
* Data source for ASRangeController.
|
||||||
*
|
*
|
||||||
@@ -88,15 +102,10 @@ NS_ASSUME_NONNULL_BEGIN
|
|||||||
*/
|
*/
|
||||||
- (CGSize)viewportSizeForRangeController:(ASRangeController *)rangeController;
|
- (CGSize)viewportSizeForRangeController:(ASRangeController *)rangeController;
|
||||||
|
|
||||||
/**
|
|
||||||
* Fetch nodes at specific index paths.
|
|
||||||
*
|
|
||||||
* @param rangeController Sender.
|
|
||||||
*
|
|
||||||
* @param indexPaths Index paths.
|
|
||||||
*/
|
|
||||||
- (NSArray *)rangeController:(ASRangeController *)rangeController nodesAtIndexPaths:(NSArray *)indexPaths;
|
- (NSArray *)rangeController:(ASRangeController *)rangeController nodesAtIndexPaths:(NSArray *)indexPaths;
|
||||||
|
|
||||||
|
- (ASDisplayNode *)rangeController:(ASRangeController *)rangeController nodeAtIndexPath:(NSIndexPath *)indexPath;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -15,8 +15,33 @@
|
|||||||
#import "ASRangeHandlerRender.h"
|
#import "ASRangeHandlerRender.h"
|
||||||
#import "ASRangeHandlerPreload.h"
|
#import "ASRangeHandlerPreload.h"
|
||||||
#import "ASInternalHelpers.h"
|
#import "ASInternalHelpers.h"
|
||||||
|
#import "ASLayoutController.h"
|
||||||
|
#import "ASLayoutRangeType.h"
|
||||||
|
|
||||||
@interface ASRangeController () {
|
@implementation ASRangeController
|
||||||
|
|
||||||
|
- (void)visibleNodeIndexPathsDidChangeWithScrollDirection:(ASScrollDirection)scrollDirection
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)configureContentView:(UIView *)contentView forCellNode:(ASCellNode *)node
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)setTuningParameters:(ASRangeTuningParameters)tuningParameters forRangeType:(ASLayoutRangeType)rangeType
|
||||||
|
{
|
||||||
|
[_layoutController setTuningParameters:tuningParameters forRangeType:rangeType];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (ASRangeTuningParameters)tuningParametersForRangeType:(ASLayoutRangeType)rangeType
|
||||||
|
{
|
||||||
|
return [_layoutController tuningParametersForRangeType:rangeType];
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
@interface ASRangeControllerStable ()
|
||||||
|
{
|
||||||
BOOL _rangeIsValid;
|
BOOL _rangeIsValid;
|
||||||
|
|
||||||
// keys should be ASLayoutRangeTypes and values NSSets containing NSIndexPaths
|
// keys should be ASLayoutRangeTypes and values NSSets containing NSIndexPaths
|
||||||
@@ -29,19 +54,21 @@
|
|||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@implementation ASRangeController
|
@implementation ASRangeControllerStable
|
||||||
|
|
||||||
|
- (instancetype)init
|
||||||
|
{
|
||||||
|
if (!(self = [super init])) {
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
- (instancetype)init {
|
|
||||||
self = [super init];
|
|
||||||
if (self != nil) {
|
|
||||||
_rangeIsValid = YES;
|
_rangeIsValid = YES;
|
||||||
_rangeTypeIndexPaths = [NSMutableDictionary dictionary];
|
_rangeTypeIndexPaths = [NSMutableDictionary dictionary];
|
||||||
_rangeTypeHandlers = @{
|
_rangeTypeHandlers = @{
|
||||||
@(ASLayoutRangeTypeVisible) : [[ASRangeHandlerVisible alloc] init],
|
@(ASLayoutRangeTypeVisible) : [[ASRangeHandlerVisible alloc] init],
|
||||||
@(ASLayoutRangeTypeRender): [[ASRangeHandlerRender alloc] init],
|
@(ASLayoutRangeTypeDisplay) : [[ASRangeHandlerRender alloc] init],
|
||||||
@(ASLayoutRangeTypePreload): [[ASRangeHandlerPreload alloc] init],
|
@(ASLayoutRangeTypeFetchData): [[ASRangeHandlerPreload alloc] init],
|
||||||
};
|
};
|
||||||
}
|
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
@@ -111,6 +138,7 @@
|
|||||||
|
|
||||||
NSSet *visibleNodePathsSet = [NSSet setWithArray:visibleNodePaths];
|
NSSet *visibleNodePathsSet = [NSSet setWithArray:visibleNodePaths];
|
||||||
CGSize viewportSize = [_dataSource viewportSizeForRangeController:self];
|
CGSize viewportSize = [_dataSource viewportSizeForRangeController:self];
|
||||||
|
[_layoutController setViewportSize:viewportSize];
|
||||||
|
|
||||||
// the layout controller needs to know what the current visible indices are to calculate range offsets
|
// the layout controller needs to know what the current visible indices are to calculate range offsets
|
||||||
if ([_layoutController respondsToSelector:@selector(setVisibleNodeIndexPaths:)]) {
|
if ([_layoutController respondsToSelector:@selector(setVisibleNodeIndexPaths:)]) {
|
||||||
@@ -124,10 +152,8 @@
|
|||||||
// this delegate decide what happens when a node is added or removed from a range
|
// this delegate decide what happens when a node is added or removed from a range
|
||||||
id<ASRangeHandler> rangeHandler = _rangeTypeHandlers[rangeKey];
|
id<ASRangeHandler> rangeHandler = _rangeTypeHandlers[rangeKey];
|
||||||
|
|
||||||
if (!_rangeIsValid || [_layoutController shouldUpdateForVisibleIndexPaths:visibleNodePaths viewportSize:viewportSize rangeType:rangeType]) {
|
if (!_rangeIsValid || [_layoutController shouldUpdateForVisibleIndexPaths:visibleNodePaths rangeType:rangeType]) {
|
||||||
NSSet *indexPaths = [_layoutController indexPathsForScrolling:_scrollDirection
|
NSSet *indexPaths = [_layoutController indexPathsForScrolling:_scrollDirection rangeType:rangeType];
|
||||||
viewportSize:viewportSize
|
|
||||||
rangeType:rangeType];
|
|
||||||
|
|
||||||
// Notify to remove indexpaths that are leftover that are not visible or included in the _layoutController calculated paths
|
// Notify to remove indexpaths that are leftover that are not visible or included in the _layoutController calculated paths
|
||||||
// This value may be nil for the first call of this method.
|
// This value may be nil for the first call of this method.
|
||||||
@@ -172,7 +198,7 @@
|
|||||||
|
|
||||||
- (BOOL)shouldSkipVisibleNodesForRangeType:(ASLayoutRangeType)rangeType
|
- (BOOL)shouldSkipVisibleNodesForRangeType:(ASLayoutRangeType)rangeType
|
||||||
{
|
{
|
||||||
return rangeType == ASLayoutRangeTypeRender;
|
return rangeType == ASLayoutRangeTypeDisplay;
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma mark - ASDataControllerDelegete
|
#pragma mark - ASDataControllerDelegete
|
||||||
|
|||||||
@@ -72,25 +72,18 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
CGSize viewportSize = [_dataSource viewportSizeForRangeController:self];
|
CGSize viewportSize = [_dataSource viewportSizeForRangeController:self];
|
||||||
|
[_layoutController setViewportSize:viewportSize];
|
||||||
|
|
||||||
// the layout controller needs to know what the current visible indices are to calculate range offsets
|
// the layout controller needs to know what the current visible indices are to calculate range offsets
|
||||||
if ([_layoutController respondsToSelector:@selector(setVisibleNodeIndexPaths:)]) {
|
if ([_layoutController respondsToSelector:@selector(setVisibleNodeIndexPaths:)]) {
|
||||||
[_layoutController setVisibleNodeIndexPaths:visibleNodePaths];
|
[_layoutController setVisibleNodeIndexPaths:visibleNodePaths];
|
||||||
}
|
}
|
||||||
|
|
||||||
NSSet *fetchDataIndexPaths = [_layoutController indexPathsForScrolling:_scrollDirection
|
NSSet *fetchDataIndexPaths = [_layoutController indexPathsForScrolling:_scrollDirection rangeType:ASLayoutRangeTypeFetchData];
|
||||||
viewportSize:viewportSize
|
NSSet *displayIndexPaths = [_layoutController indexPathsForScrolling:_scrollDirection rangeType:ASLayoutRangeTypeDisplay];
|
||||||
rangeType:ASLayoutRangeTypeFetchData];
|
NSSet *visibleIndexPaths = [_layoutController indexPathsForScrolling:_scrollDirection rangeType:ASLayoutRangeTypeVisible];
|
||||||
|
|
||||||
NSSet *displayIndexPaths = [_layoutController indexPathsForScrolling:_scrollDirection
|
//NSSet *visibleNodePathsSet = [NSSet setWithArray:visibleNodePaths];
|
||||||
viewportSize:viewportSize
|
|
||||||
rangeType:ASLayoutRangeTypeDisplay];
|
|
||||||
|
|
||||||
NSSet *visibleIndexPaths = [_layoutController indexPathsForScrolling:_scrollDirection
|
|
||||||
viewportSize:viewportSize
|
|
||||||
rangeType:ASLayoutRangeTypeVisible];
|
|
||||||
|
|
||||||
NSSet *visibleNodePathsSet = [NSSet setWithArray:visibleNodePaths];
|
|
||||||
//NSLog(@"visible sets are equal: %d", [visibleIndexPaths isEqualToSet:visibleNodePathsSet]);
|
//NSLog(@"visible sets are equal: %d", [visibleIndexPaths isEqualToSet:visibleNodePathsSet]);
|
||||||
|
|
||||||
// Typically the fetchDataIndexPaths will be the largest, and be a superset of the others, though it may be disjoint.
|
// Typically the fetchDataIndexPaths will be the largest, and be a superset of the others, though it may be disjoint.
|
||||||
|
|||||||
@@ -14,13 +14,13 @@
|
|||||||
|
|
||||||
- (void)node:(ASDisplayNode *)node enteredRangeOfType:(ASLayoutRangeType)rangeType
|
- (void)node:(ASDisplayNode *)node enteredRangeOfType:(ASLayoutRangeType)rangeType
|
||||||
{
|
{
|
||||||
ASDisplayNodeAssert(rangeType == ASLayoutRangeTypePreload, @"Preload delegate should not handle other ranges");
|
ASDisplayNodeAssert(rangeType == ASLayoutRangeTypeFetchData, @"Preload delegate should not handle other ranges");
|
||||||
[node enterInterfaceState:ASInterfaceStateFetchData];
|
[node enterInterfaceState:ASInterfaceStateFetchData];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)node:(ASDisplayNode *)node exitedRangeOfType:(ASLayoutRangeType)rangeType
|
- (void)node:(ASDisplayNode *)node exitedRangeOfType:(ASLayoutRangeType)rangeType
|
||||||
{
|
{
|
||||||
ASDisplayNodeAssert(rangeType == ASLayoutRangeTypePreload, @"Preload delegate should not handle other ranges");
|
ASDisplayNodeAssert(rangeType == ASLayoutRangeTypeFetchData, @"Preload delegate should not handle other ranges");
|
||||||
[node exitInterfaceState:ASInterfaceStateFetchData];
|
[node exitInterfaceState:ASInterfaceStateFetchData];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -44,7 +44,7 @@
|
|||||||
if (![ASDisplayNode shouldUseNewRenderingRange]) {
|
if (![ASDisplayNode shouldUseNewRenderingRange]) {
|
||||||
for (CALayer *layer in [self.workingWindow.layer.sublayers copy]) {
|
for (CALayer *layer in [self.workingWindow.layer.sublayers copy]) {
|
||||||
ASDisplayNode *node = layer.asyncdisplaykit_node;
|
ASDisplayNode *node = layer.asyncdisplaykit_node;
|
||||||
[self node:node exitedRangeOfType:ASLayoutRangeTypeRender];
|
[self node:node exitedRangeOfType:ASLayoutRangeTypeDisplay];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -52,7 +52,7 @@
|
|||||||
- (void)node:(ASDisplayNode *)node enteredRangeOfType:(ASLayoutRangeType)rangeType
|
- (void)node:(ASDisplayNode *)node enteredRangeOfType:(ASLayoutRangeType)rangeType
|
||||||
{
|
{
|
||||||
ASDisplayNodeAssertMainThread();
|
ASDisplayNodeAssertMainThread();
|
||||||
ASDisplayNodeAssert(rangeType == ASLayoutRangeTypeRender, @"Render delegate should not handle other ranges");
|
ASDisplayNodeAssert(rangeType == ASLayoutRangeTypeDisplay, @"Render delegate should not handle other ranges");
|
||||||
|
|
||||||
// If a node had previously been onscreen but now is only in the working range,
|
// If a node had previously been onscreen but now is only in the working range,
|
||||||
// ensure its view is not orphaned in a UITableViewCell in the reuse pool.
|
// ensure its view is not orphaned in a UITableViewCell in the reuse pool.
|
||||||
@@ -64,6 +64,7 @@
|
|||||||
[node enterInterfaceState:ASInterfaceStateDisplay];
|
[node enterInterfaceState:ASInterfaceStateDisplay];
|
||||||
|
|
||||||
|
|
||||||
|
ASDisplayNodeAssert(![ASDisplayNode shouldUseNewRenderingRange], @"It should no longer be possible to reach this point with the new display range enabled");
|
||||||
if ([ASDisplayNode shouldUseNewRenderingRange]) {
|
if ([ASDisplayNode shouldUseNewRenderingRange]) {
|
||||||
[node recursivelyEnsureDisplaySynchronously:NO];
|
[node recursivelyEnsureDisplaySynchronously:NO];
|
||||||
} else {
|
} else {
|
||||||
@@ -79,7 +80,7 @@
|
|||||||
- (void)node:(ASDisplayNode *)node exitedRangeOfType:(ASLayoutRangeType)rangeType
|
- (void)node:(ASDisplayNode *)node exitedRangeOfType:(ASLayoutRangeType)rangeType
|
||||||
{
|
{
|
||||||
ASDisplayNodeAssertMainThread();
|
ASDisplayNodeAssertMainThread();
|
||||||
ASDisplayNodeAssert(rangeType == ASLayoutRangeTypeRender, @"Render delegate should not handle other ranges");
|
ASDisplayNodeAssert(rangeType == ASLayoutRangeTypeDisplay, @"Render delegate should not handle other ranges");
|
||||||
|
|
||||||
// This code is tricky. There are several possible states a node can be in when it reaches this point.
|
// This code is tricky. There are several possible states a node can be in when it reaches this point.
|
||||||
// 1. Layer-backed vs view-backed nodes. AS of this writing, only ASCellNodes arrive here, which are always view-backed —
|
// 1. Layer-backed vs view-backed nodes. AS of this writing, only ASCellNodes arrive here, which are always view-backed —
|
||||||
@@ -101,6 +102,8 @@
|
|||||||
// The node calls clearCurrentContents and suspends display
|
// The node calls clearCurrentContents and suspends display
|
||||||
[node exitInterfaceState:ASInterfaceStateDisplay];
|
[node exitInterfaceState:ASInterfaceStateDisplay];
|
||||||
|
|
||||||
|
ASDisplayNodeAssert(![ASDisplayNode shouldUseNewRenderingRange], @"It should no longer be possible to reach this point with the new display range enabled");
|
||||||
|
|
||||||
if ([ASDisplayNode shouldUseNewRenderingRange]) {
|
if ([ASDisplayNode shouldUseNewRenderingRange]) {
|
||||||
if (![node isLayerBacked]) {
|
if (![node isLayerBacked]) {
|
||||||
[node.view removeFromSuperview];
|
[node.view removeFromSuperview];
|
||||||
|
|||||||
@@ -10,13 +10,16 @@
|
|||||||
#import <CoreGraphics/CoreGraphics.h>
|
#import <CoreGraphics/CoreGraphics.h>
|
||||||
|
|
||||||
#import "ASBaseDefines.h"
|
#import "ASBaseDefines.h"
|
||||||
|
#import "ASLayoutController.h"
|
||||||
|
|
||||||
NS_ASSUME_NONNULL_BEGIN
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
ASDISPLAYNODE_EXTERN_C_BEGIN
|
ASDISPLAYNODE_EXTERN_C_BEGIN
|
||||||
|
|
||||||
CGRect asdk_CGRectExpandHorizontally(CGRect rect, CGFloat negativeMultiplier, CGFloat positiveMultiplier);
|
CGRect CGRectExpandToRangeWithScrollableDirections(CGRect rect,
|
||||||
CGRect asdk_CGRectExpandVertically(CGRect rect, CGFloat negativeMultiplier, CGFloat positiveMultiplier);
|
ASRangeTuningParameters tuningParameters,
|
||||||
|
ASScrollDirection scrollableDirections,
|
||||||
|
ASScrollDirection scrollDirection);
|
||||||
|
|
||||||
ASDISPLAYNODE_EXTERN_C_END
|
ASDISPLAYNODE_EXTERN_C_END
|
||||||
|
|
||||||
|
|||||||
@@ -7,25 +7,74 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#import "CGRect+ASConvenience.h"
|
#import "CGRect+ASConvenience.h"
|
||||||
|
#import "ASScrollDirection.h"
|
||||||
|
#import "ASLayoutController.h"
|
||||||
|
|
||||||
CGRect asdk_CGRectExpandHorizontally(CGRect rect, CGFloat negativeMultiplier, CGFloat positiveMultiplier) {
|
struct ASDirectionalScreenfulBuffer {
|
||||||
CGFloat negativeDirectionWidth = negativeMultiplier * rect.size.width;
|
CGFloat positiveDirection; // Positive relative to iOS Core Animation layer coordinate space.
|
||||||
CGFloat positiveDirectionWidth = positiveMultiplier * rect.size.width;
|
CGFloat negativeDirection;
|
||||||
CGFloat width = negativeDirectionWidth + rect.size.width + positiveDirectionWidth;
|
};
|
||||||
CGFloat originX = rect.origin.x - negativeDirectionWidth;
|
typedef struct ASDirectionalScreenfulBuffer ASDirectionalScreenfulBuffer;
|
||||||
return CGRectMake(originX,
|
|
||||||
rect.origin.y,
|
ASDirectionalScreenfulBuffer ASDirectionalScreenfulBufferHorizontal(ASScrollDirection scrollDirection,
|
||||||
width,
|
ASRangeTuningParameters rangeTuningParameters)
|
||||||
rect.size.height);
|
{
|
||||||
|
ASDirectionalScreenfulBuffer horizontalBuffer = {0, 0};
|
||||||
|
BOOL movingRight = ASScrollDirectionContainsRight(scrollDirection);
|
||||||
|
|
||||||
|
horizontalBuffer.positiveDirection = movingRight ? rangeTuningParameters.leadingBufferScreenfuls
|
||||||
|
: rangeTuningParameters.trailingBufferScreenfuls;
|
||||||
|
horizontalBuffer.negativeDirection = movingRight ? rangeTuningParameters.trailingBufferScreenfuls
|
||||||
|
: rangeTuningParameters.leadingBufferScreenfuls;
|
||||||
|
return horizontalBuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
CGRect asdk_CGRectExpandVertically(CGRect rect, CGFloat negativeMultiplier, CGFloat positiveMultiplier) {
|
ASDirectionalScreenfulBuffer ASDirectionalScreenfulBufferVertical(ASScrollDirection scrollDirection,
|
||||||
CGFloat negativeDirectionHeight = negativeMultiplier * rect.size.height;
|
ASRangeTuningParameters rangeTuningParameters)
|
||||||
CGFloat positiveDirectionHeight = positiveMultiplier * rect.size.height;
|
{
|
||||||
CGFloat height = negativeDirectionHeight + rect.size.height + positiveDirectionHeight;
|
ASDirectionalScreenfulBuffer verticalBuffer = {0, 0};
|
||||||
CGFloat originY = rect.origin.y - negativeDirectionHeight;
|
BOOL movingDown = ASScrollDirectionContainsDown(scrollDirection);
|
||||||
return CGRectMake(rect.origin.x,
|
|
||||||
originY,
|
verticalBuffer.positiveDirection = movingDown ? rangeTuningParameters.leadingBufferScreenfuls
|
||||||
rect.size.width,
|
: rangeTuningParameters.trailingBufferScreenfuls;
|
||||||
height);
|
verticalBuffer.negativeDirection = movingDown ? rangeTuningParameters.trailingBufferScreenfuls
|
||||||
|
: rangeTuningParameters.leadingBufferScreenfuls;
|
||||||
|
return verticalBuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CGRect CGRectExpandHorizontally(CGRect rect, ASDirectionalScreenfulBuffer buffer)
|
||||||
|
{
|
||||||
|
CGFloat negativeDirectionWidth = buffer.negativeDirection * rect.size.width;
|
||||||
|
CGFloat positiveDirectionWidth = buffer.positiveDirection * rect.size.width;
|
||||||
|
rect.size.width = negativeDirectionWidth + rect.size.width + positiveDirectionWidth;
|
||||||
|
rect.origin.x -= negativeDirectionWidth;
|
||||||
|
return rect;
|
||||||
|
}
|
||||||
|
|
||||||
|
CGRect CGRectExpandVertically(CGRect rect, ASDirectionalScreenfulBuffer buffer)
|
||||||
|
{
|
||||||
|
CGFloat negativeDirectionHeight = buffer.negativeDirection * rect.size.height;
|
||||||
|
CGFloat positiveDirectionHeight = buffer.positiveDirection * rect.size.height;
|
||||||
|
rect.size.height = negativeDirectionHeight + rect.size.height + positiveDirectionHeight;
|
||||||
|
rect.origin.y -= negativeDirectionHeight;
|
||||||
|
return rect;
|
||||||
|
}
|
||||||
|
|
||||||
|
CGRect CGRectExpandToRangeWithScrollableDirections(CGRect rect, ASRangeTuningParameters tuningParameters,
|
||||||
|
ASScrollDirection scrollableDirections, ASScrollDirection scrollDirection)
|
||||||
|
{
|
||||||
|
// Can scroll horizontally - expand the range appropriately
|
||||||
|
if (ASScrollDirectionContainsHorizontalDirection(scrollableDirections)) {
|
||||||
|
ASDirectionalScreenfulBuffer horizontalBuffer = ASDirectionalScreenfulBufferHorizontal(scrollDirection, tuningParameters);
|
||||||
|
rect = CGRectExpandHorizontally(rect, horizontalBuffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Can scroll vertically - expand the range appropriately
|
||||||
|
if (ASScrollDirectionContainsVerticalDirection(scrollableDirections)) {
|
||||||
|
ASDirectionalScreenfulBuffer verticalBuffer = ASDirectionalScreenfulBufferVertical(scrollDirection, tuningParameters);
|
||||||
|
rect = CGRectExpandVertically(rect, verticalBuffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
return rect;
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -10,8 +10,9 @@
|
|||||||
|
|
||||||
@implementation UICollectionViewLayout (ASConvenience)
|
@implementation UICollectionViewLayout (ASConvenience)
|
||||||
|
|
||||||
- (BOOL)asdk_isFlowLayout {
|
- (BOOL)asdk_isFlowLayout
|
||||||
return [self isKindOfClass:UICollectionViewFlowLayout.class];
|
{
|
||||||
|
return [self isKindOfClass:[UICollectionViewFlowLayout class]];
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|||||||
@@ -60,6 +60,7 @@ typedef NS_OPTIONS(NSUInteger, ASHierarchyState)
|
|||||||
// These methods are recursive, and either union or remove the provided interfaceState to all sub-elements.
|
// These methods are recursive, and either union or remove the provided interfaceState to all sub-elements.
|
||||||
- (void)enterInterfaceState:(ASInterfaceState)interfaceState;
|
- (void)enterInterfaceState:(ASInterfaceState)interfaceState;
|
||||||
- (void)exitInterfaceState:(ASInterfaceState)interfaceState;
|
- (void)exitInterfaceState:(ASInterfaceState)interfaceState;
|
||||||
|
- (void)recursivelySetInterfaceState:(ASInterfaceState)interfaceState;
|
||||||
|
|
||||||
// These methods are recursive, and either union or remove the provided hierarchyState to all sub-elements.
|
// These methods are recursive, and either union or remove the provided hierarchyState to all sub-elements.
|
||||||
- (void)enterHierarchyState:(ASHierarchyState)hierarchyState;
|
- (void)enterHierarchyState:(ASHierarchyState)hierarchyState;
|
||||||
|
|||||||
@@ -250,7 +250,8 @@
|
|||||||
_messageToViewOrLayer(setNeedsDisplay);
|
_messageToViewOrLayer(setNeedsDisplay);
|
||||||
|
|
||||||
if ([ASDisplayNode shouldUseNewRenderingRange]) {
|
if ([ASDisplayNode shouldUseNewRenderingRange]) {
|
||||||
if (_layer && !self.isSynchronous) {
|
BOOL shouldDisplay = ((_interfaceState & ASInterfaceStateDisplay) == ASInterfaceStateDisplay);
|
||||||
|
if (_layer && !_flags.synchronous && shouldDisplay) {
|
||||||
[ASDisplayNode scheduleNodeForDisplay:self];
|
[ASDisplayNode scheduleNodeForDisplay:self];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,10 +13,15 @@
|
|||||||
|
|
||||||
#import "ViewController.h"
|
#import "ViewController.h"
|
||||||
|
|
||||||
|
#import <AsyncDisplayKit/ASDisplayNode.h>
|
||||||
|
#import <AsyncDisplayKit/ASDisplayNode+Beta.h>
|
||||||
|
|
||||||
@implementation AppDelegate
|
@implementation AppDelegate
|
||||||
|
|
||||||
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
|
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
|
||||||
{
|
{
|
||||||
|
[ASDisplayNode setShouldUseNewRenderingRange:YES];
|
||||||
|
|
||||||
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
|
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
|
||||||
self.window.backgroundColor = [UIColor whiteColor];
|
self.window.backgroundColor = [UIColor whiteColor];
|
||||||
self.window.rootViewController = [[UINavigationController alloc] initWithRootViewController:[[ViewController alloc] init]];
|
self.window.rootViewController = [[UINavigationController alloc] initWithRootViewController:[[ViewController alloc] init]];
|
||||||
|
|||||||
@@ -51,7 +51,7 @@
|
|||||||
ASRangeTuningParameters rangeTuningParameters;
|
ASRangeTuningParameters rangeTuningParameters;
|
||||||
rangeTuningParameters.leadingBufferScreenfuls = 1.0;
|
rangeTuningParameters.leadingBufferScreenfuls = 1.0;
|
||||||
rangeTuningParameters.trailingBufferScreenfuls = 0.5;
|
rangeTuningParameters.trailingBufferScreenfuls = 0.5;
|
||||||
[_tableNode.view setTuningParameters:rangeTuningParameters forRangeType:ASLayoutRangeTypeRender];
|
[_tableNode.view setTuningParameters:rangeTuningParameters forRangeType:ASLayoutRangeTypeDisplay];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
|
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
|
||||||
|
|||||||
@@ -9,6 +9,9 @@
|
|||||||
#import <AsyncDisplayKit/AsyncDisplayKit.h>
|
#import <AsyncDisplayKit/AsyncDisplayKit.h>
|
||||||
|
|
||||||
@interface RandomCoreGraphicsNode : ASCellNode
|
@interface RandomCoreGraphicsNode : ASCellNode
|
||||||
|
{
|
||||||
|
ASTextNode *_indexPathTextNode;
|
||||||
|
}
|
||||||
|
|
||||||
@property (nonatomic) NSIndexPath *indexPath;
|
@property (nonatomic) NSIndexPath *indexPath;
|
||||||
|
|
||||||
|
|||||||
@@ -42,6 +42,37 @@
|
|||||||
CGColorSpaceRelease(colorSpace);
|
CGColorSpaceRelease(colorSpace);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (instancetype)init
|
||||||
|
{
|
||||||
|
if (!(self = [super init])) {
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
_indexPathTextNode = [[ASTextNode alloc] init];
|
||||||
|
[self addSubnode:_indexPathTextNode];
|
||||||
|
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)setIndexPath:(NSIndexPath *)indexPath
|
||||||
|
{
|
||||||
|
_indexPath = indexPath;
|
||||||
|
_indexPathTextNode.attributedString = [[NSAttributedString alloc] initWithString:[indexPath description] attributes:nil];
|
||||||
|
}
|
||||||
|
|
||||||
|
//- (ASLayoutSpec *)layoutSpecThatFits:(ASSizeRange)constrainedSize
|
||||||
|
//{
|
||||||
|
// ASStackLayoutSpec *stackSpec = [ASStackLayoutSpec stackLayoutSpecWithDirection:ASStackLayoutDirectionVertical spacing:0 justifyContent:ASStackLayoutJustifyContentStart alignItems:ASStackLayoutAlignItemsStart children:@[_indexPathTextNode]];
|
||||||
|
// stackSpec.flexGrow = YES;
|
||||||
|
// return stackSpec;
|
||||||
|
//}
|
||||||
|
|
||||||
|
- (void)layout
|
||||||
|
{
|
||||||
|
_indexPathTextNode.frame = self.bounds;
|
||||||
|
[super layout];
|
||||||
|
}
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
- (void)fetchData
|
- (void)fetchData
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user