mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-23 22:55:00 +00:00
Functioning Preload range
Refactor how we do ranges so they can be arbitrarily managed. Introduce the concept of a preload range.
This commit is contained in:
@@ -138,6 +138,12 @@
|
|||||||
05F20AA41A15733C00DCA68A /* ASImageProtocols.h in Headers */ = {isa = PBXBuildFile; fileRef = 05F20AA31A15733C00DCA68A /* ASImageProtocols.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
05F20AA41A15733C00DCA68A /* ASImageProtocols.h in Headers */ = {isa = PBXBuildFile; fileRef = 05F20AA31A15733C00DCA68A /* ASImageProtocols.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||||
1950C4491A3BB5C1005C8279 /* ASEqualityHelpers.h in Headers */ = {isa = PBXBuildFile; fileRef = 1950C4481A3BB5C1005C8279 /* ASEqualityHelpers.h */; };
|
1950C4491A3BB5C1005C8279 /* ASEqualityHelpers.h in Headers */ = {isa = PBXBuildFile; fileRef = 1950C4481A3BB5C1005C8279 /* ASEqualityHelpers.h */; };
|
||||||
2911485C1A77147A005D0878 /* ASControlNodeTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 2911485B1A77147A005D0878 /* ASControlNodeTests.m */; };
|
2911485C1A77147A005D0878 /* ASControlNodeTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 2911485B1A77147A005D0878 /* ASControlNodeTests.m */; };
|
||||||
|
292C599F1A956527007E5DD6 /* ASLayoutRangeType.h in Headers */ = {isa = PBXBuildFile; fileRef = 292C59991A956527007E5DD6 /* ASLayoutRangeType.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||||
|
292C59A01A956527007E5DD6 /* ASPreloadRangeDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = 292C599A1A956527007E5DD6 /* ASPreloadRangeDelegate.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||||
|
292C59A11A956527007E5DD6 /* ASPreloadRangeDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = 292C599B1A956527007E5DD6 /* ASPreloadRangeDelegate.mm */; };
|
||||||
|
292C59A21A956527007E5DD6 /* ASRangeDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = 292C599C1A956527007E5DD6 /* ASRangeDelegate.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||||
|
292C59A31A956527007E5DD6 /* ASRenderRangeDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = 292C599D1A956527007E5DD6 /* ASRenderRangeDelegate.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||||
|
292C59A41A956527007E5DD6 /* ASRenderRangeDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = 292C599E1A956527007E5DD6 /* ASRenderRangeDelegate.mm */; };
|
||||||
3C9C128519E616EF00E942A0 /* ASTableViewTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 3C9C128419E616EF00E942A0 /* ASTableViewTests.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
|
3C9C128519E616EF00E942A0 /* ASTableViewTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 3C9C128419E616EF00E942A0 /* ASTableViewTests.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
|
||||||
464052201A3F83C40061C0BA /* ASDataController.h in Headers */ = {isa = PBXBuildFile; fileRef = 464052191A3F83C40061C0BA /* ASDataController.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
464052201A3F83C40061C0BA /* ASDataController.h in Headers */ = {isa = PBXBuildFile; fileRef = 464052191A3F83C40061C0BA /* ASDataController.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||||
464052211A3F83C40061C0BA /* ASDataController.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4640521A1A3F83C40061C0BA /* ASDataController.mm */; };
|
464052211A3F83C40061C0BA /* ASDataController.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4640521A1A3F83C40061C0BA /* ASDataController.mm */; };
|
||||||
@@ -284,6 +290,12 @@
|
|||||||
05F20AA31A15733C00DCA68A /* ASImageProtocols.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASImageProtocols.h; sourceTree = "<group>"; };
|
05F20AA31A15733C00DCA68A /* ASImageProtocols.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASImageProtocols.h; sourceTree = "<group>"; };
|
||||||
1950C4481A3BB5C1005C8279 /* ASEqualityHelpers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASEqualityHelpers.h; sourceTree = "<group>"; };
|
1950C4481A3BB5C1005C8279 /* ASEqualityHelpers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASEqualityHelpers.h; sourceTree = "<group>"; };
|
||||||
2911485B1A77147A005D0878 /* ASControlNodeTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASControlNodeTests.m; sourceTree = "<group>"; };
|
2911485B1A77147A005D0878 /* ASControlNodeTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASControlNodeTests.m; sourceTree = "<group>"; };
|
||||||
|
292C59991A956527007E5DD6 /* ASLayoutRangeType.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASLayoutRangeType.h; sourceTree = "<group>"; };
|
||||||
|
292C599A1A956527007E5DD6 /* ASPreloadRangeDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASPreloadRangeDelegate.h; sourceTree = "<group>"; };
|
||||||
|
292C599B1A956527007E5DD6 /* ASPreloadRangeDelegate.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASPreloadRangeDelegate.mm; sourceTree = "<group>"; };
|
||||||
|
292C599C1A956527007E5DD6 /* ASRangeDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASRangeDelegate.h; sourceTree = "<group>"; };
|
||||||
|
292C599D1A956527007E5DD6 /* ASRenderRangeDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASRenderRangeDelegate.h; sourceTree = "<group>"; };
|
||||||
|
292C599E1A956527007E5DD6 /* ASRenderRangeDelegate.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASRenderRangeDelegate.mm; sourceTree = "<group>"; };
|
||||||
3C9C128419E616EF00E942A0 /* ASTableViewTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASTableViewTests.m; sourceTree = "<group>"; };
|
3C9C128419E616EF00E942A0 /* ASTableViewTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASTableViewTests.m; sourceTree = "<group>"; };
|
||||||
464052191A3F83C40061C0BA /* ASDataController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASDataController.h; sourceTree = "<group>"; };
|
464052191A3F83C40061C0BA /* ASDataController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASDataController.h; sourceTree = "<group>"; };
|
||||||
4640521A1A3F83C40061C0BA /* ASDataController.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASDataController.mm; sourceTree = "<group>"; };
|
4640521A1A3F83C40061C0BA /* ASDataController.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASDataController.mm; sourceTree = "<group>"; };
|
||||||
@@ -463,12 +475,21 @@
|
|||||||
058D09E7195D050800B7D73C /* ASHighlightOverlayLayer.mm */,
|
058D09E7195D050800B7D73C /* ASHighlightOverlayLayer.mm */,
|
||||||
05F20AA31A15733C00DCA68A /* ASImageProtocols.h */,
|
05F20AA31A15733C00DCA68A /* ASImageProtocols.h */,
|
||||||
4640521D1A3F83C40061C0BA /* ASLayoutController.h */,
|
4640521D1A3F83C40061C0BA /* ASLayoutController.h */,
|
||||||
|
|
||||||
|
292C59991A956527007E5DD6 /* ASLayoutRangeType.h */,
|
||||||
4640521E1A3F83C40061C0BA /* ASMultidimensionalArrayUtils.h */,
|
4640521E1A3F83C40061C0BA /* ASMultidimensionalArrayUtils.h */,
|
||||||
4640521F1A3F83C40061C0BA /* ASMultidimensionalArrayUtils.mm */,
|
4640521F1A3F83C40061C0BA /* ASMultidimensionalArrayUtils.mm */,
|
||||||
058D09E8195D050800B7D73C /* ASMutableAttributedStringBuilder.h */,
|
058D09E8195D050800B7D73C /* ASMutableAttributedStringBuilder.h */,
|
||||||
058D09E9195D050800B7D73C /* ASMutableAttributedStringBuilder.m */,
|
058D09E9195D050800B7D73C /* ASMutableAttributedStringBuilder.m */,
|
||||||
055F1A3619ABD413004DAFF1 /* ASRangeController.h */,
|
055F1A3619ABD413004DAFF1 /* ASRangeController.h */,
|
||||||
055F1A3719ABD413004DAFF1 /* ASRangeController.mm */,
|
055F1A3719ABD413004DAFF1 /* ASRangeController.mm */,
|
||||||
|
292C599A1A956527007E5DD6 /* ASPreloadRangeDelegate.h */,
|
||||||
|
292C599B1A956527007E5DD6 /* ASPreloadRangeDelegate.mm */,
|
||||||
|
055F1A3619ABD413004DAFF1 /* ASRangeController.h */,
|
||||||
|
055F1A3719ABD413004DAFF1 /* ASRangeController.mm */,
|
||||||
|
292C599C1A956527007E5DD6 /* ASRangeDelegate.h */,
|
||||||
|
292C599D1A956527007E5DD6 /* ASRenderRangeDelegate.h */,
|
||||||
|
292C599E1A956527007E5DD6 /* ASRenderRangeDelegate.mm */,
|
||||||
058D09EA195D050800B7D73C /* ASTextNodeCoreTextAdditions.h */,
|
058D09EA195D050800B7D73C /* ASTextNodeCoreTextAdditions.h */,
|
||||||
058D09EB195D050800B7D73C /* ASTextNodeCoreTextAdditions.m */,
|
058D09EB195D050800B7D73C /* ASTextNodeCoreTextAdditions.m */,
|
||||||
058D09EC195D050800B7D73C /* ASTextNodeRenderer.h */,
|
058D09EC195D050800B7D73C /* ASTextNodeRenderer.h */,
|
||||||
@@ -574,6 +595,7 @@
|
|||||||
058D0A51195D05CB00B7D73C /* ASTextNode.h in Headers */,
|
058D0A51195D05CB00B7D73C /* ASTextNode.h in Headers */,
|
||||||
058D0A52195D05CB00B7D73C /* ASTextNode.mm in Headers */,
|
058D0A52195D05CB00B7D73C /* ASTextNode.mm in Headers */,
|
||||||
055F1A3819ABD413004DAFF1 /* ASRangeController.h in Headers */,
|
055F1A3819ABD413004DAFF1 /* ASRangeController.h in Headers */,
|
||||||
|
292C59A31A956527007E5DD6 /* ASRenderRangeDelegate.h in Headers */,
|
||||||
055F1A3419ABD3E3004DAFF1 /* ASTableView.h in Headers */,
|
055F1A3419ABD3E3004DAFF1 /* ASTableView.h in Headers */,
|
||||||
0574D5E219C110940097DC25 /* ASTableViewProtocols.h in Headers */,
|
0574D5E219C110940097DC25 /* ASTableViewProtocols.h in Headers */,
|
||||||
055F1A3C19ABD43F004DAFF1 /* ASCellNode.h in Headers */,
|
055F1A3C19ABD43F004DAFF1 /* ASCellNode.h in Headers */,
|
||||||
@@ -594,6 +616,7 @@
|
|||||||
058D0A61195D05DC00B7D73C /* ASTextNodeTextKitHelpers.h in Headers */,
|
058D0A61195D05DC00B7D73C /* ASTextNodeTextKitHelpers.h in Headers */,
|
||||||
058D0A62195D05DC00B7D73C /* ASTextNodeTextKitHelpers.mm in Headers */,
|
058D0A62195D05DC00B7D73C /* ASTextNodeTextKitHelpers.mm in Headers */,
|
||||||
058D0A63195D05DC00B7D73C /* ASTextNodeTypes.h in Headers */,
|
058D0A63195D05DC00B7D73C /* ASTextNodeTypes.h in Headers */,
|
||||||
|
292C599F1A956527007E5DD6 /* ASLayoutRangeType.h in Headers */,
|
||||||
464052251A3F83C40061C0BA /* ASMultidimensionalArrayUtils.h in Headers */,
|
464052251A3F83C40061C0BA /* ASMultidimensionalArrayUtils.h in Headers */,
|
||||||
058D0A64195D05DC00B7D73C /* ASTextNodeWordKerner.h in Headers */,
|
058D0A64195D05DC00B7D73C /* ASTextNodeWordKerner.h in Headers */,
|
||||||
058D0A65195D05DC00B7D73C /* ASTextNodeWordKerner.m in Headers */,
|
058D0A65195D05DC00B7D73C /* ASTextNodeWordKerner.m in Headers */,
|
||||||
@@ -615,6 +638,7 @@
|
|||||||
058D0A83195D060300B7D73C /* ASBaseDefines.h in Headers */,
|
058D0A83195D060300B7D73C /* ASBaseDefines.h in Headers */,
|
||||||
058D0A84195D060300B7D73C /* ASDisplayNodeExtraIvars.h in Headers */,
|
058D0A84195D060300B7D73C /* ASDisplayNodeExtraIvars.h in Headers */,
|
||||||
AC3C4A511A1139C100143C57 /* ASCollectionView.h in Headers */,
|
AC3C4A511A1139C100143C57 /* ASCollectionView.h in Headers */,
|
||||||
|
292C59A01A956527007E5DD6 /* ASPreloadRangeDelegate.h in Headers */,
|
||||||
055B9FA81A1C154B00035D6D /* ASNetworkImageNode.h in Headers */,
|
055B9FA81A1C154B00035D6D /* ASNetworkImageNode.h in Headers */,
|
||||||
054963491A1EA066000F8E56 /* ASBasicImageDownloader.h in Headers */,
|
054963491A1EA066000F8E56 /* ASBasicImageDownloader.h in Headers */,
|
||||||
AC3C4A541A113EEC00143C57 /* ASCollectionViewProtocols.h in Headers */,
|
AC3C4A541A113EEC00143C57 /* ASCollectionViewProtocols.h in Headers */,
|
||||||
@@ -634,6 +658,7 @@
|
|||||||
058D0A7B195D05F900B7D73C /* ASDisplayNodeInternal.h in Headers */,
|
058D0A7B195D05F900B7D73C /* ASDisplayNodeInternal.h in Headers */,
|
||||||
058D0A7C195D05F900B7D73C /* ASImageNode+CGExtras.h in Headers */,
|
058D0A7C195D05F900B7D73C /* ASImageNode+CGExtras.h in Headers */,
|
||||||
058D0A7D195D05F900B7D73C /* ASImageNode+CGExtras.m in Headers */,
|
058D0A7D195D05F900B7D73C /* ASImageNode+CGExtras.m in Headers */,
|
||||||
|
292C59A21A956527007E5DD6 /* ASRangeDelegate.h in Headers */,
|
||||||
058D0A7F195D05F900B7D73C /* ASSentinel.h in Headers */,
|
058D0A7F195D05F900B7D73C /* ASSentinel.h in Headers */,
|
||||||
058D0A80195D05F900B7D73C /* ASSentinel.m in Headers */,
|
058D0A80195D05F900B7D73C /* ASSentinel.m in Headers */,
|
||||||
058D0A81195D05F900B7D73C /* ASThread.h in Headers */,
|
058D0A81195D05F900B7D73C /* ASThread.h in Headers */,
|
||||||
@@ -770,8 +795,10 @@
|
|||||||
464052261A3F83C40061C0BA /* ASMultidimensionalArrayUtils.mm in Sources */,
|
464052261A3F83C40061C0BA /* ASMultidimensionalArrayUtils.mm in Sources */,
|
||||||
055B9FA91A1C154B00035D6D /* ASNetworkImageNode.mm in Sources */,
|
055B9FA91A1C154B00035D6D /* ASNetworkImageNode.mm in Sources */,
|
||||||
058D0A1D195D050800B7D73C /* ASTextNodeRenderer.mm in Sources */,
|
058D0A1D195D050800B7D73C /* ASTextNodeRenderer.mm in Sources */,
|
||||||
|
292C59A41A956527007E5DD6 /* ASRenderRangeDelegate.mm in Sources */,
|
||||||
058D0A2A195D050800B7D73C /* ASDisplayNode+UIViewBridge.mm in Sources */,
|
058D0A2A195D050800B7D73C /* ASDisplayNode+UIViewBridge.mm in Sources */,
|
||||||
AC3C4A521A1139C100143C57 /* ASCollectionView.mm in Sources */,
|
AC3C4A521A1139C100143C57 /* ASCollectionView.mm in Sources */,
|
||||||
|
292C59A11A956527007E5DD6 /* ASPreloadRangeDelegate.mm in Sources */,
|
||||||
058D0A20195D050800B7D73C /* ASTextNodeWordKerner.m in Sources */,
|
058D0A20195D050800B7D73C /* ASTextNodeWordKerner.m in Sources */,
|
||||||
058D0A1A195D050800B7D73C /* ASHighlightOverlayLayer.mm in Sources */,
|
058D0A1A195D050800B7D73C /* ASHighlightOverlayLayer.mm in Sources */,
|
||||||
464052231A3F83C40061C0BA /* ASFlowLayoutController.mm in Sources */,
|
464052231A3F83C40061C0BA /* ASFlowLayoutController.mm in Sources */,
|
||||||
|
|||||||
@@ -39,7 +39,7 @@
|
|||||||
* Defaults to the render range having one sceenful both leading and trailing and the preload range having two
|
* Defaults to the render range having one sceenful both leading and trailing and the preload range having two
|
||||||
* screenfuls in both directions.
|
* screenfuls in both directions.
|
||||||
*/
|
*/
|
||||||
- (ASRangeTuningParameters)tuningParametersForRange:(ASLayoutRange)range;
|
- (ASRangeTuningParameters)tuningParametersForRangeType:(ASLayoutRangeType)rangeType;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the tuning parameters for a range.
|
* Set the tuning parameters for a range.
|
||||||
@@ -47,7 +47,7 @@
|
|||||||
* @param tuningParameters The tuning parameters to store for a range.
|
* @param tuningParameters The tuning parameters to store for a range.
|
||||||
* @param range The range to set the tuning parameters for.
|
* @param range The range to set the tuning parameters for.
|
||||||
*/
|
*/
|
||||||
- (void)setTuningParameters:(ASRangeTuningParameters)tuningParameters forRange:(ASLayoutRange)range;
|
- (void)setTuningParameters:(ASRangeTuningParameters)tuningParameters forRangeType:(ASLayoutRangeType)rangeType;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initializer.
|
* Initializer.
|
||||||
|
|||||||
@@ -199,24 +199,24 @@ static BOOL _isInterceptedSelector(SEL sel)
|
|||||||
super.delegate = (id<UICollectionViewDelegate>)_proxyDelegate;
|
super.delegate = (id<UICollectionViewDelegate>)_proxyDelegate;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)setTuningParameters:(ASRangeTuningParameters)tuningParameters forRange:(ASLayoutRange)range
|
- (void)setTuningParameters:(ASRangeTuningParameters)tuningParameters forRangeType:(ASLayoutRangeType)rangeType
|
||||||
{
|
{
|
||||||
[_layoutController setTuningParameters:tuningParameters forRange:range];
|
[_layoutController setTuningParameters:tuningParameters forRangeType:rangeType];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (ASRangeTuningParameters)tuningParametersForRange:(ASLayoutRange)range
|
- (ASRangeTuningParameters)tuningParametersForRangeType:(ASLayoutRangeType)rangeType
|
||||||
{
|
{
|
||||||
return [_layoutController tuningParametersForRange:range];
|
return [_layoutController tuningParametersForRangeType:rangeType];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (ASRangeTuningParameters)rangeTuningParameters
|
- (ASRangeTuningParameters)rangeTuningParameters
|
||||||
{
|
{
|
||||||
return [self tuningParametersForRange:ASLayoutRangeRender];
|
return [self tuningParametersForRangeType:ASLayoutRangeTypeRender];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)setRangeTuningParameters:(ASRangeTuningParameters)tuningParameters
|
- (void)setRangeTuningParameters:(ASRangeTuningParameters)tuningParameters
|
||||||
{
|
{
|
||||||
[self setTuningParameters:tuningParameters forRange:ASLayoutRangeRender];
|
[self setTuningParameters:tuningParameters forRangeType:ASLayoutRangeTypeRender];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (CGSize)calculatedSizeForNodeAtIndexPath:(NSIndexPath *)indexPath
|
- (CGSize)calculatedSizeForNodeAtIndexPath:(NSIndexPath *)indexPath
|
||||||
|
|||||||
@@ -185,6 +185,14 @@
|
|||||||
*/
|
*/
|
||||||
- (void)displayDidFinish ASDISPLAYNODE_REQUIRES_SUPER;
|
- (void)displayDidFinish ASDISPLAYNODE_REQUIRES_SUPER;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @abstract Indicates that the node should fetch any external data, such as images.
|
||||||
|
*
|
||||||
|
* @discussion Subclasses may override this method to be notified when they should begin to fetch data. Fetching
|
||||||
|
* should be done asynchronously. The node is also responsible for managing the memory of any data.
|
||||||
|
*/
|
||||||
|
- (void)fetchRemoteData ASDISPLAYNODE_REQUIRES_SUPER;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @abstract Indicates that the receiver is about to display its subnodes. This method is not called if there are no
|
* @abstract Indicates that the receiver is about to display its subnodes. This method is not called if there are no
|
||||||
* subnodes present.
|
* subnodes present.
|
||||||
@@ -312,13 +320,20 @@
|
|||||||
- (void)didExitHierarchy ASDISPLAYNODE_REQUIRES_SUPER;
|
- (void)didExitHierarchy ASDISPLAYNODE_REQUIRES_SUPER;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides an opportunity to clear backing store and other memory-intensive intermediates, such as text layout managers
|
* Provides an opportunity to clear backing store and other memory-intensive intermediates, such as text layout managers.
|
||||||
* or downloaded content that can be written to a disk cache.
|
|
||||||
*
|
*
|
||||||
* @discussion Called by -recursivelyReclaimMemory. Base class implements self.contents = nil, clearing any backing
|
* @discussion Called by -recursivelyClearRendering. Base class implements self.contents = nil, clearing any backing
|
||||||
* store, for asynchronous regeneration when needed.
|
* store, for asynchronous regeneration when needed.
|
||||||
*/
|
*/
|
||||||
- (void)reclaimMemory ASDISPLAYNODE_REQUIRES_SUPER;
|
- (void)clearRendering ASDISPLAYNODE_REQUIRES_SUPER;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides an opportunity to clear any remote data for only the current node.
|
||||||
|
*
|
||||||
|
* @discussion This will not clear data recursively for all subnodes. Either call -recursivelyClearRemoteData or
|
||||||
|
* selectively clear remote data.
|
||||||
|
*/
|
||||||
|
- (void)clearRemoteData ASDISPLAYNODE_REQUIRES_SUPER;
|
||||||
|
|
||||||
|
|
||||||
/** @name Placeholders */
|
/** @name Placeholders */
|
||||||
|
|||||||
@@ -312,7 +312,7 @@ typedef CALayer *(^ASDisplayNodeLayerBlock)();
|
|||||||
- (void)recursivelySetDisplaySuspended:(BOOL)flag;
|
- (void)recursivelySetDisplaySuspended:(BOOL)flag;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @abstract Calls -reclaimMemory on the receiver and its subnode hierarchy.
|
* @abstract Calls -clearRendering on the receiver and its subnode hierarchy.
|
||||||
*
|
*
|
||||||
* @discussion Clears backing stores and other memory-intensive intermediates.
|
* @discussion Clears backing stores and other memory-intensive intermediates.
|
||||||
* If the node is removed from a visible hierarchy and then re-added, it will automatically trigger a new asynchronous display,
|
* If the node is removed from a visible hierarchy and then re-added, it will automatically trigger a new asynchronous display,
|
||||||
@@ -322,7 +322,18 @@ typedef CALayer *(^ASDisplayNodeLayerBlock)();
|
|||||||
* @see displaySuspended and setNeedsDisplay
|
* @see displaySuspended and setNeedsDisplay
|
||||||
*/
|
*/
|
||||||
|
|
||||||
- (void)recursivelyReclaimMemory;
|
- (void)recursivelyClearRendering;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @abstract Calls -clearRemoteData on the receiver and its subnode hierarchy.
|
||||||
|
*
|
||||||
|
* @discussion Clears any memory-intensive fetched content.
|
||||||
|
* This method is used to notify the node that it should purge any content that is both expensive to fetch and to
|
||||||
|
* retain in memory.
|
||||||
|
*
|
||||||
|
* @see fetchRemoteData
|
||||||
|
*/
|
||||||
|
- (void)recursivelyClearRemoteData;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @abstract Toggle displaying a placeholder over the node that covers content until the node and all subnodes are
|
* @abstract Toggle displaying a placeholder over the node that covers content until the node and all subnodes are
|
||||||
@@ -539,5 +550,9 @@ typedef CALayer *(^ASDisplayNodeLayerBlock)();
|
|||||||
@end
|
@end
|
||||||
|
|
||||||
@interface ASDisplayNode (Deprecated)
|
@interface ASDisplayNode (Deprecated)
|
||||||
|
|
||||||
|
- (void)reclaimMemory ASDISPLAYNODE_DEPRECATED;
|
||||||
|
- (void)recursivelyReclaimMemory ASDISPLAYNODE_DEPRECATED;
|
||||||
@property (nonatomic, assign) BOOL placeholderFadesOut ASDISPLAYNODE_DEPRECATED;
|
@property (nonatomic, assign) BOOL placeholderFadesOut ASDISPLAYNODE_DEPRECATED;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|||||||
@@ -90,7 +90,7 @@ void ASDisplayNodePerformBlockOnMainThread(void (^block)())
|
|||||||
// Subclasses should never override these
|
// Subclasses should never override these
|
||||||
ASDisplayNodeAssert(!ASDisplayNodeSubclassOverridesSelector(self, @selector(calculatedSize)), @"Subclass %@ must not override calculatedSize method", NSStringFromClass(self));
|
ASDisplayNodeAssert(!ASDisplayNodeSubclassOverridesSelector(self, @selector(calculatedSize)), @"Subclass %@ must not override calculatedSize method", NSStringFromClass(self));
|
||||||
ASDisplayNodeAssert(!ASDisplayNodeSubclassOverridesSelector(self, @selector(measure:)), @"Subclass %@ must not override measure method", NSStringFromClass(self));
|
ASDisplayNodeAssert(!ASDisplayNodeSubclassOverridesSelector(self, @selector(measure:)), @"Subclass %@ must not override measure method", NSStringFromClass(self));
|
||||||
ASDisplayNodeAssert(!ASDisplayNodeSubclassOverridesSelector(self, @selector(recursivelyReclaimMemory)), @"Subclass %@ must not override recursivelyReclaimMemory method", NSStringFromClass(self));
|
ASDisplayNodeAssert(!ASDisplayNodeSubclassOverridesSelector(self, @selector(recursivelyClearRendering)), @"Subclass %@ must not override recursivelyClearRendering method", NSStringFromClass(self));
|
||||||
}
|
}
|
||||||
|
|
||||||
+ (BOOL)layerBackedNodesEnabled
|
+ (BOOL)layerBackedNodesEnabled
|
||||||
@@ -1328,18 +1328,36 @@ static NSInteger incrementIfFound(NSInteger i) {
|
|||||||
[self __exitedHierarchy];
|
[self __exitedHierarchy];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)reclaimMemory
|
- (void)clearRendering
|
||||||
{
|
{
|
||||||
self.layer.contents = nil;
|
self.layer.contents = nil;
|
||||||
_placeholderLayer.contents = nil;
|
_placeholderLayer.contents = nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)recursivelyReclaimMemory
|
- (void)recursivelyClearRendering
|
||||||
{
|
{
|
||||||
for (ASDisplayNode *subnode in self.subnodes) {
|
for (ASDisplayNode *subnode in self.subnodes) {
|
||||||
[subnode recursivelyReclaimMemory];
|
[subnode recursivelyClearRendering];
|
||||||
}
|
}
|
||||||
[self reclaimMemory];
|
[self clearRendering];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)fetchRemoteData
|
||||||
|
{
|
||||||
|
// subclass override
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)clearRemoteData
|
||||||
|
{
|
||||||
|
// subclass override
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)recursivelyClearRemoteData
|
||||||
|
{
|
||||||
|
for (ASDisplayNode *subnode in self.subnodes) {
|
||||||
|
[subnode recursivelyClearRemoteData];
|
||||||
|
}
|
||||||
|
[self clearRemoteData];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)layout
|
- (void)layout
|
||||||
@@ -1460,6 +1478,7 @@ static NSInteger incrementIfFound(NSInteger i) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#pragma mark - Pending View State
|
#pragma mark - Pending View State
|
||||||
- (_ASPendingState *)pendingViewState
|
- (_ASPendingState *)pendingViewState
|
||||||
{
|
{
|
||||||
@@ -1786,4 +1805,14 @@ static const char *ASDisplayNodeAssociatedNodeKey = "ASAssociatedNode";
|
|||||||
return self.placeholderFadeDuration > 0.0;
|
return self.placeholderFadeDuration > 0.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)reclaimMemory
|
||||||
|
{
|
||||||
|
[self clearRendering];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)recursivelyReclaimMemory
|
||||||
|
{
|
||||||
|
[self recursivelyClearRendering];
|
||||||
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|||||||
@@ -162,9 +162,9 @@ typedef void(^ASMultiplexImageLoadCompletionBlock)(UIImage *image, id imageIdent
|
|||||||
}
|
}
|
||||||
|
|
||||||
#pragma mark - ASDisplayNode Overrides
|
#pragma mark - ASDisplayNode Overrides
|
||||||
- (void)reclaimMemory
|
- (void)clearRendering
|
||||||
{
|
{
|
||||||
[super reclaimMemory]; // This actually clears the contents, so we need to do this first for our displayedImageIdentifier to be meaningful.
|
[super clearRendering]; // This actually clears the contents, so we need to do this first for our displayedImageIdentifier to be meaningful.
|
||||||
[self _setDisplayedImageIdentifier:nil withImage:nil];
|
[self _setDisplayedImageIdentifier:nil withImage:nil];
|
||||||
|
|
||||||
if (_downloadIdentifier) {
|
if (_downloadIdentifier) {
|
||||||
@@ -177,6 +177,13 @@ typedef void(^ASMultiplexImageLoadCompletionBlock)(UIImage *image, id imageIdent
|
|||||||
{
|
{
|
||||||
[super displayWillStart];
|
[super displayWillStart];
|
||||||
|
|
||||||
|
[self fetchRemoteData];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)fetchRemoteData
|
||||||
|
{
|
||||||
|
[super fetchRemoteData];
|
||||||
|
|
||||||
[self _loadImageIdentifiers];
|
[self _loadImageIdentifiers];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -123,9 +123,16 @@
|
|||||||
return _delegate;
|
return _delegate;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)reclaimMemory
|
- (void)displayWillStart
|
||||||
{
|
{
|
||||||
[super reclaimMemory];
|
[super displayWillStart];
|
||||||
|
|
||||||
|
[self fetchRemoteData];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)clearRemoteData
|
||||||
|
{
|
||||||
|
[super clearRemoteData];
|
||||||
|
|
||||||
{
|
{
|
||||||
ASDN::MutexLocker l(_lock);
|
ASDN::MutexLocker l(_lock);
|
||||||
@@ -136,10 +143,10 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)displayWillStart
|
- (void)fetchRemoteData
|
||||||
{
|
{
|
||||||
[super displayWillStart];
|
[super fetchRemoteData];
|
||||||
|
|
||||||
{
|
{
|
||||||
ASDN::MutexLocker l(_lock);
|
ASDN::MutexLocker l(_lock);
|
||||||
[self _lazilyLoadImageIfNecessary];
|
[self _lazilyLoadImageIfNecessary];
|
||||||
|
|||||||
@@ -32,22 +32,22 @@
|
|||||||
/**
|
/**
|
||||||
* Tuning parameters for a range.
|
* Tuning parameters for a range.
|
||||||
*
|
*
|
||||||
* @param range The range to get the tuning parameters for.
|
* @param rangeType The range to get the tuning parameters for.
|
||||||
*
|
*
|
||||||
* @returns A tuning parameter value for the given range.
|
* @returns A tuning parameter value for the given range.
|
||||||
*
|
*
|
||||||
* Defaults to the render range having one sceenful both leading and trailing and the preload range having two
|
* Defaults to the render range having one sceenful both leading and trailing and the preload range having two
|
||||||
* screenfuls in both directions.
|
* screenfuls in both directions.
|
||||||
*/
|
*/
|
||||||
- (ASRangeTuningParameters)tuningParametersForRange:(ASLayoutRange)range;
|
- (ASRangeTuningParameters)tuningParametersForRangeType:(ASLayoutRangeType)rangeType;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the tuning parameters for a range.
|
* Set the tuning parameters for a range.
|
||||||
*
|
*
|
||||||
* @param tuningParameters The tuning parameters to store for a range.
|
* @param tuningParameters The tuning parameters to store for a range.
|
||||||
* @param range The range to set the tuning parameters for.
|
* @param rangeType The range to set the tuning parameters for.
|
||||||
*/
|
*/
|
||||||
- (void)setTuningParameters:(ASRangeTuningParameters)tuningParameters forRange:(ASLayoutRange)range;
|
- (void)setTuningParameters:(ASRangeTuningParameters)tuningParameters forRangeType:(ASLayoutRangeType)rangeType;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* initializer.
|
* initializer.
|
||||||
|
|||||||
@@ -201,24 +201,24 @@ static BOOL _isInterceptedSelector(SEL sel)
|
|||||||
[_dataController reloadDataWithAnimationOption:UITableViewRowAnimationNone];
|
[_dataController reloadDataWithAnimationOption:UITableViewRowAnimationNone];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)setTuningParameters:(ASRangeTuningParameters)tuningParameters forRange:(ASLayoutRange)range
|
- (void)setTuningParameters:(ASRangeTuningParameters)tuningParameters forRangeType:(ASLayoutRangeType)rangeType
|
||||||
{
|
{
|
||||||
[_layoutController setTuningParameters:tuningParameters forRange:range];
|
[_layoutController setTuningParameters:tuningParameters forRangeType:rangeType];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (ASRangeTuningParameters)tuningParametersForRange:(ASLayoutRange)range
|
- (ASRangeTuningParameters)tuningParametersForRangeType:(ASLayoutRangeType)rangeType
|
||||||
{
|
{
|
||||||
return [_layoutController tuningParametersForRange:range];
|
return [_layoutController tuningParametersForRangeType:rangeType];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (ASRangeTuningParameters)rangeTuningParameters
|
- (ASRangeTuningParameters)rangeTuningParameters
|
||||||
{
|
{
|
||||||
return [self tuningParametersForRange:ASLayoutRangeRender];
|
return [self tuningParametersForRangeType:ASLayoutRangeTypeRender];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)setRangeTuningParameters:(ASRangeTuningParameters)tuningParameters
|
- (void)setRangeTuningParameters:(ASRangeTuningParameters)tuningParameters
|
||||||
{
|
{
|
||||||
[self setTuningParameters:tuningParameters forRange:ASLayoutRangeRender];
|
[self setTuningParameters:tuningParameters forRangeType:ASLayoutRangeTypeRender];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (ASCellNode *)nodeForRowAtIndexPath:(NSIndexPath *)indexPath
|
- (ASCellNode *)nodeForRowAtIndexPath:(NSIndexPath *)indexPath
|
||||||
|
|||||||
@@ -212,12 +212,12 @@ ASDISPLAYNODE_INLINE CGFloat ceilPixelValue(CGFloat f)
|
|||||||
[self _invalidateRenderer];
|
[self _invalidateRenderer];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)reclaimMemory
|
- (void)clearRendering
|
||||||
{
|
{
|
||||||
// We discard the backing store and renderer to prevent the very large
|
// We discard the backing store and renderer to prevent the very large
|
||||||
// memory overhead of maintaining these for all text nodes. They can be
|
// memory overhead of maintaining these for all text nodes. They can be
|
||||||
// regenerated when layout is necessary.
|
// regenerated when layout is necessary.
|
||||||
[super reclaimMemory]; // ASDisplayNode will set layer.contents = nil
|
[super clearRendering]; // ASDisplayNode will set layer.contents = nil
|
||||||
[self _invalidateRenderer];
|
[self _invalidateRenderer];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,10 @@
|
|||||||
// Copyright 2004-present Facebook. All Rights Reserved.
|
/* Copyright (c) 2014-present, Facebook, Inc.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the BSD-style license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
*/
|
||||||
|
|
||||||
#import <UIKit/UIKit.h>
|
#import <UIKit/UIKit.h>
|
||||||
#import <AsyncDisplayKit/ASDealloc2MainObject.h>
|
#import <AsyncDisplayKit/ASDealloc2MainObject.h>
|
||||||
|
|||||||
@@ -1,4 +1,10 @@
|
|||||||
// Copyright 2004-present Facebook. All Rights Reserved.
|
/* Copyright (c) 2014-present, Facebook, Inc.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the BSD-style license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
*/
|
||||||
|
|
||||||
#import "ASDataController.h"
|
#import "ASDataController.h"
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,10 @@
|
|||||||
// Copyright 2004-present Facebook. All Rights Reserved.
|
/* Copyright (c) 2014-present, Facebook, Inc.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the BSD-style license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
*/
|
||||||
|
|
||||||
#import <AsyncDisplayKit/ASLayoutController.h>
|
#import <AsyncDisplayKit/ASLayoutController.h>
|
||||||
#import <AsyncDisplayKit/ASBaseDefines.h>
|
#import <AsyncDisplayKit/ASBaseDefines.h>
|
||||||
@@ -14,9 +20,9 @@ typedef NS_ENUM(NSUInteger, ASFlowLayoutDirection) {
|
|||||||
*/
|
*/
|
||||||
@interface ASFlowLayoutController : NSObject <ASLayoutController>
|
@interface ASFlowLayoutController : NSObject <ASLayoutController>
|
||||||
|
|
||||||
- (void)setTuningParameters:(ASRangeTuningParameters)tuningParameters forRange:(ASLayoutRange)range;
|
- (void)setTuningParameters:(ASRangeTuningParameters)tuningParameters forRangeType:(ASLayoutRangeType)rangeType;
|
||||||
|
|
||||||
- (ASRangeTuningParameters)tuningParametersForRange:(ASLayoutRange)range;
|
- (ASRangeTuningParameters)tuningParametersForRangeType:(ASLayoutRangeType)rangeType;
|
||||||
|
|
||||||
@property (nonatomic, readonly, assign) ASFlowLayoutDirection layoutDirection;
|
@property (nonatomic, readonly, assign) ASFlowLayoutDirection layoutDirection;
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,10 @@
|
|||||||
// Copyright 2004-present Facebook. All Rights Reserved.
|
/* Copyright (c) 2014-present, Facebook, Inc.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the BSD-style license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
*/
|
||||||
|
|
||||||
#import "ASFlowLayoutController.h"
|
#import "ASFlowLayoutController.h"
|
||||||
|
|
||||||
@@ -33,17 +39,14 @@ static const CGFloat kASFlowLayoutControllerRefreshingThreshold = 0.3;
|
|||||||
|
|
||||||
_layoutDirection = layoutDirection;
|
_layoutDirection = layoutDirection;
|
||||||
|
|
||||||
_tuningParameterMap = {
|
_tuningParameterMap = std::vector<ASRangeTuningParameters>(2);
|
||||||
{
|
_tuningParameterMap[ASLayoutRangeTypePreload] = {
|
||||||
// Render
|
.leadingBufferScreenfuls = 2,
|
||||||
.leadingBufferScreenfuls = 1,
|
.trailingBufferScreenfuls = 1
|
||||||
.trailingBufferScreenfuls = 1
|
};
|
||||||
},
|
_tuningParameterMap[ASLayoutRangeTypeRender] = {
|
||||||
{
|
.leadingBufferScreenfuls = 3,
|
||||||
// Preload
|
.trailingBufferScreenfuls = 2
|
||||||
.leadingBufferScreenfuls = 2,
|
|
||||||
.trailingBufferScreenfuls = 2
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
@@ -51,28 +54,28 @@ static const CGFloat kASFlowLayoutControllerRefreshingThreshold = 0.3;
|
|||||||
|
|
||||||
#pragma mark - Tuning Parameters
|
#pragma mark - Tuning Parameters
|
||||||
|
|
||||||
- (ASRangeTuningParameters)tuningParametersForRange:(ASLayoutRange)range
|
- (ASRangeTuningParameters)tuningParametersForRangeType:(ASLayoutRangeType)rangeType
|
||||||
{
|
{
|
||||||
ASDisplayNodeAssert(range < _tuningParameterMap.size(), @"Requesting a range that is OOB for the configured tuning parameters");
|
ASDisplayNodeAssert(rangeType < _tuningParameterMap.size(), @"Requesting a range that is OOB for the configured tuning parameters");
|
||||||
return _tuningParameterMap[range];
|
return _tuningParameterMap[rangeType];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)setTuningParameters:(ASRangeTuningParameters)tuningParameters forRange:(ASLayoutRange)range
|
- (void)setTuningParameters:(ASRangeTuningParameters)tuningParameters forRangeType:(ASLayoutRangeType)rangeType
|
||||||
{
|
{
|
||||||
ASDisplayNodeAssert(range < _tuningParameterMap.size(), @"Requesting a range that is OOB for the configured tuning parameters");
|
ASDisplayNodeAssert(rangeType < _tuningParameterMap.size(), @"Requesting a range that is OOB for the configured tuning parameters");
|
||||||
_tuningParameterMap[range] = tuningParameters;
|
_tuningParameterMap[rangeType] = tuningParameters;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Support for the deprecated tuningParameters property
|
// Support for the deprecated tuningParameters property
|
||||||
- (ASRangeTuningParameters)tuningParameters
|
- (ASRangeTuningParameters)tuningParameters
|
||||||
{
|
{
|
||||||
return [self tuningParametersForRange:ASLayoutRangeRender];
|
return [self tuningParametersForRangeType:ASLayoutRangeTypeRender];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Support for the deprecated tuningParameters property
|
// Support for the deprecated tuningParameters property
|
||||||
- (void)setTuningParameters:(ASRangeTuningParameters)tuningParameters
|
- (void)setTuningParameters:(ASRangeTuningParameters)tuningParameters
|
||||||
{
|
{
|
||||||
[self setTuningParameters:tuningParameters forRange:ASLayoutRangeRender];
|
[self setTuningParameters:tuningParameters forRangeType:ASLayoutRangeTypeRender];
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma mark - Editing
|
#pragma mark - Editing
|
||||||
@@ -120,7 +123,7 @@ static const CGFloat kASFlowLayoutControllerRefreshingThreshold = 0.3;
|
|||||||
|
|
||||||
#pragma mark - Visible Indices
|
#pragma mark - Visible Indices
|
||||||
|
|
||||||
- (BOOL)shouldUpdateForVisibleIndexPaths:(NSArray *)indexPaths viewportSize:(CGSize)viewportSize range:(ASLayoutRange)range
|
- (BOOL)shouldUpdateForVisibleIndexPaths:(NSArray *)indexPaths viewportSize:(CGSize)viewportSize rangeType:(ASLayoutRangeType)rangeType
|
||||||
{
|
{
|
||||||
if (!indexPaths.count) {
|
if (!indexPaths.count) {
|
||||||
return NO;
|
return NO;
|
||||||
@@ -128,9 +131,9 @@ static const CGFloat kASFlowLayoutControllerRefreshingThreshold = 0.3;
|
|||||||
|
|
||||||
std::pair<int, int> rangeStartPos, rangeEndPos;
|
std::pair<int, int> rangeStartPos, rangeEndPos;
|
||||||
|
|
||||||
if (range < _rangeStartPos.size() && range < _rangeEndPos.size()) {
|
if (rangeType < _rangeStartPos.size() && rangeType < _rangeEndPos.size()) {
|
||||||
rangeStartPos = _rangeStartPos[range];
|
rangeStartPos = _rangeStartPos[rangeType];
|
||||||
rangeEndPos = _rangeEndPos[range];
|
rangeEndPos = _rangeEndPos[rangeType];
|
||||||
}
|
}
|
||||||
|
|
||||||
std::pair<int, int> startPos, endPos;
|
std::pair<int, int> startPos, endPos;
|
||||||
@@ -147,7 +150,7 @@ static const CGFloat kASFlowLayoutControllerRefreshingThreshold = 0.3;
|
|||||||
- (BOOL)shouldUpdateForVisibleIndexPath:(NSArray *)indexPaths
|
- (BOOL)shouldUpdateForVisibleIndexPath:(NSArray *)indexPaths
|
||||||
viewportSize:(CGSize)viewportSize
|
viewportSize:(CGSize)viewportSize
|
||||||
{
|
{
|
||||||
return [self shouldUpdateForVisibleIndexPaths:indexPaths viewportSize:viewportSize range:ASLayoutRangeRender];
|
return [self shouldUpdateForVisibleIndexPaths:indexPaths viewportSize:viewportSize rangeType:ASLayoutRangeTypeRender];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)setVisibleNodeIndexPaths:(NSArray *)indexPaths
|
- (void)setVisibleNodeIndexPaths:(NSArray *)indexPaths
|
||||||
@@ -159,7 +162,7 @@ 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:(enum ASScrollDirection)scrollDirection viewportSize:(CGSize)viewportSize range:(ASLayoutRange)range
|
- (NSSet *)indexPathsForScrolling:(enum ASScrollDirection)scrollDirection viewportSize:(CGSize)viewportSize rangeType:(ASLayoutRangeType)rangeType
|
||||||
{
|
{
|
||||||
CGFloat viewportScreenMetric;
|
CGFloat viewportScreenMetric;
|
||||||
ASScrollDirection leadingDirection;
|
ASScrollDirection leadingDirection;
|
||||||
@@ -176,12 +179,12 @@ static const CGFloat kASFlowLayoutControllerRefreshingThreshold = 0.3;
|
|||||||
leadingDirection = ASScrollDirectionUp;
|
leadingDirection = ASScrollDirectionUp;
|
||||||
}
|
}
|
||||||
|
|
||||||
ASRangeTuningParameters tuningParameters = [self tuningParametersForRange:range];
|
ASRangeTuningParameters tuningParameters = [self tuningParametersForRangeType:rangeType];
|
||||||
CGFloat backScreens = scrollDirection == leadingDirection ? tuningParameters.leadingBufferScreenfuls : tuningParameters.trailingBufferScreenfuls;
|
CGFloat backScreens = scrollDirection == leadingDirection ? tuningParameters.leadingBufferScreenfuls : tuningParameters.trailingBufferScreenfuls;
|
||||||
CGFloat frontScreens = scrollDirection == leadingDirection ? tuningParameters.trailingBufferScreenfuls : tuningParameters.leadingBufferScreenfuls;
|
CGFloat frontScreens = scrollDirection == leadingDirection ? tuningParameters.trailingBufferScreenfuls : tuningParameters.leadingBufferScreenfuls;
|
||||||
|
|
||||||
std::pair<int, int> startIter = ASFindIndexForRange(_nodeSizes, _visibleRangeStartPos, - backScreens * viewportSize.height, _layoutDirection);
|
std::pair<int, int> startIter = ASFindIndexForRange(_nodeSizes, _visibleRangeStartPos, - backScreens * viewportScreenMetric, _layoutDirection);
|
||||||
std::pair<int, int> endIter = ASFindIndexForRange(_nodeSizes, _visibleRangeEndPos, frontScreens * viewportSize.height, _layoutDirection);
|
std::pair<int, int> endIter = ASFindIndexForRange(_nodeSizes, _visibleRangeEndPos, frontScreens * viewportScreenMetric, _layoutDirection);
|
||||||
|
|
||||||
NSMutableSet *indexPathSet = [[NSMutableSet alloc] init];
|
NSMutableSet *indexPathSet = [[NSMutableSet alloc] init];
|
||||||
|
|
||||||
@@ -203,7 +206,7 @@ static const CGFloat kASFlowLayoutControllerRefreshingThreshold = 0.3;
|
|||||||
- (NSSet *)indexPathsForScrolling:(enum ASScrollDirection)scrollDirection
|
- (NSSet *)indexPathsForScrolling:(enum ASScrollDirection)scrollDirection
|
||||||
viewportSize:(CGSize)viewportSize
|
viewportSize:(CGSize)viewportSize
|
||||||
{
|
{
|
||||||
return [self indexPathsForScrolling:scrollDirection viewportSize:viewportSize range:ASLayoutRangeRender];
|
return [self indexPathsForScrolling:scrollDirection viewportSize:viewportSize rangeType:ASLayoutRangeTypeRender];
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma mark - Utility
|
#pragma mark - Utility
|
||||||
|
|||||||
@@ -1,8 +1,15 @@
|
|||||||
// Copyright 2004-present Facebook. All Rights Reserved.
|
/* Copyright (c) 2014-present, Facebook, Inc.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the BSD-style license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
*/
|
||||||
|
|
||||||
#import <UIKit/UIKit.h>
|
#import <UIKit/UIKit.h>
|
||||||
|
|
||||||
#import <AsyncDisplayKit/ASBaseDefines.h>
|
#import <AsyncDisplayKit/ASBaseDefines.h>
|
||||||
|
#import <AsyncDisplayKit/ASLayoutRangeType.h>
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
CGFloat leadingBufferScreenfuls;
|
CGFloat leadingBufferScreenfuls;
|
||||||
@@ -17,11 +24,6 @@ typedef NS_ENUM(NSInteger, ASScrollDirection) {
|
|||||||
ASScrollDirectionDown,
|
ASScrollDirectionDown,
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef NS_ENUM(NSInteger, ASLayoutRange) {
|
|
||||||
ASLayoutRangeRender,
|
|
||||||
ASLayoutRangePreload
|
|
||||||
};
|
|
||||||
|
|
||||||
@protocol ASLayoutController <NSObject>
|
@protocol ASLayoutController <NSObject>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -29,7 +31,7 @@ typedef NS_ENUM(NSInteger, ASLayoutRange) {
|
|||||||
*
|
*
|
||||||
* 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.
|
||||||
*/
|
*/
|
||||||
- (ASRangeTuningParameters)tuningParametersForRange:(ASLayoutRange)range;
|
- (ASRangeTuningParameters)tuningParametersForRangeType:(ASLayoutRangeType)rangeType;
|
||||||
|
|
||||||
- (void)insertNodesAtIndexPaths:(NSArray *)indexPaths withSizes:(NSArray *)nodeSizes;
|
- (void)insertNodesAtIndexPaths:(NSArray *)indexPaths withSizes:(NSArray *)nodeSizes;
|
||||||
|
|
||||||
@@ -41,9 +43,9 @@ typedef NS_ENUM(NSInteger, ASLayoutRange) {
|
|||||||
|
|
||||||
- (void)setVisibleNodeIndexPaths:(NSArray *)indexPaths;
|
- (void)setVisibleNodeIndexPaths:(NSArray *)indexPaths;
|
||||||
|
|
||||||
- (BOOL)shouldUpdateForVisibleIndexPaths:(NSArray *)indexPaths viewportSize:(CGSize)viewportSize range:(ASLayoutRange)range;
|
- (BOOL)shouldUpdateForVisibleIndexPaths:(NSArray *)indexPaths viewportSize:(CGSize)viewportSize rangeType:(ASLayoutRangeType)rangeType;
|
||||||
|
|
||||||
- (NSSet *)indexPathsForScrolling:(enum ASScrollDirection)scrollDirection viewportSize:(CGSize)viewportSize range:(ASLayoutRange)range;
|
- (NSSet *)indexPathsForScrolling:(enum ASScrollDirection)scrollDirection viewportSize:(CGSize)viewportSize rangeType:(ASLayoutRangeType)rangeType;
|
||||||
|
|
||||||
@property (nonatomic, assign) ASRangeTuningParameters tuningParameters ASDISPLAYNODE_DEPRECATED;
|
@property (nonatomic, assign) ASRangeTuningParameters tuningParameters ASDISPLAYNODE_DEPRECATED;
|
||||||
|
|
||||||
|
|||||||
15
AsyncDisplayKit/Details/ASLayoutRangeType.h
Normal file
15
AsyncDisplayKit/Details/ASLayoutRangeType.h
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
/* Copyright (c) 2014-present, Facebook, Inc.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the BSD-style license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#import <Foundation/Foundation.h>
|
||||||
|
|
||||||
|
typedef NS_ENUM(NSInteger, ASLayoutRangeType) {
|
||||||
|
ASLayoutRangeTypeRender,
|
||||||
|
ASLayoutRangeTypePreload,
|
||||||
|
ASLayoutRangeTypeCount
|
||||||
|
};
|
||||||
@@ -1,4 +1,10 @@
|
|||||||
// Copyright 2004-present Facebook. All Rights Reserved.
|
/* Copyright (c) 2014-present, Facebook, Inc.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the BSD-style license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
*/
|
||||||
|
|
||||||
#import <Foundation/Foundation.h>
|
#import <Foundation/Foundation.h>
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,10 @@
|
|||||||
// Copyright 2004-present Facebook. All Rights Reserved.
|
/* Copyright (c) 2014-present, Facebook, Inc.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the BSD-style license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
*/
|
||||||
|
|
||||||
#import "ASAssert.h"
|
#import "ASAssert.h"
|
||||||
#import "ASMultidimensionalArrayUtils.h"
|
#import "ASMultidimensionalArrayUtils.h"
|
||||||
|
|||||||
15
AsyncDisplayKit/Details/ASPreloadRangeDelegate.h
Normal file
15
AsyncDisplayKit/Details/ASPreloadRangeDelegate.h
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
/* Copyright (c) 2014-present, Facebook, Inc.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the BSD-style license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#import <Foundation/Foundation.h>
|
||||||
|
|
||||||
|
#import <AsyncDisplayKit/ASRangeDelegate.h>
|
||||||
|
|
||||||
|
@interface ASPreloadRangeDelegate : NSObject <ASRangeDelegate>
|
||||||
|
|
||||||
|
@end
|
||||||
26
AsyncDisplayKit/Details/ASPreloadRangeDelegate.mm
Normal file
26
AsyncDisplayKit/Details/ASPreloadRangeDelegate.mm
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
/* Copyright (c) 2014-present, Facebook, Inc.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the BSD-style license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#import "ASPreloadRangeDelegate.h"
|
||||||
|
|
||||||
|
#import "ASDisplayNode.h"
|
||||||
|
#import "ASDisplayNode+Subclasses.h"
|
||||||
|
|
||||||
|
@implementation ASPreloadRangeDelegate
|
||||||
|
|
||||||
|
- (void)node:(ASDisplayNode *)node enteredRangeType:(ASLayoutRangeType)rangeType
|
||||||
|
{
|
||||||
|
[node fetchRemoteData];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)node:(ASDisplayNode *)node exitedRangeType:(ASLayoutRangeType)rangeType
|
||||||
|
{
|
||||||
|
[node clearRemoteData];
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
@@ -20,7 +20,7 @@
|
|||||||
* Working range controller.
|
* Working range controller.
|
||||||
*
|
*
|
||||||
* Used internally by ASTableView and potentially by a future ASCollectionView. Observes the visible range, maintains
|
* Used internally by ASTableView and potentially by a future ASCollectionView. Observes the visible range, maintains
|
||||||
* a working range, and is responsible for handling AsyncDisplayKit machinery (sizing cell nodes, enqueueing and
|
* a working range, and is responsible for handling AsyncDisplayKit machinery (sizing cell nodes,x enqueueing and
|
||||||
* cancelling their asynchronous layout and display, and so on).
|
* cancelling their asynchronous layout and display, and so on).
|
||||||
*/
|
*/
|
||||||
@interface ASRangeController : ASDealloc2MainObject <ASDataControllerDelegate>
|
@interface ASRangeController : ASDealloc2MainObject <ASDataControllerDelegate>
|
||||||
|
|||||||
@@ -11,62 +11,16 @@
|
|||||||
#import "ASAssert.h"
|
#import "ASAssert.h"
|
||||||
#import "ASDisplayNodeExtras.h"
|
#import "ASDisplayNodeExtras.h"
|
||||||
#import "ASDisplayNodeInternal.h"
|
#import "ASDisplayNodeInternal.h"
|
||||||
#import "ASLayoutController.h"
|
|
||||||
|
|
||||||
#import "ASMultiDimensionalArrayUtils.h"
|
#import "ASMultiDimensionalArrayUtils.h"
|
||||||
|
#import "ASRenderRangeDelegate.h"
|
||||||
@interface ASDisplayNode (ASRangeController)
|
#import "ASPreloadRangeDelegate.h"
|
||||||
|
|
||||||
- (void)display;
|
|
||||||
- (void)recursivelyDisplay;
|
|
||||||
|
|
||||||
@end
|
|
||||||
|
|
||||||
@implementation ASDisplayNode (ASRangeController)
|
|
||||||
|
|
||||||
- (void)display
|
|
||||||
{
|
|
||||||
if (![self __shouldLoadViewOrLayer]) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
ASDisplayNodeAssertMainThread();
|
|
||||||
ASDisplayNodeAssert(self.nodeLoaded, @"backing store must be loaded before calling -display");
|
|
||||||
|
|
||||||
CALayer *layer = self.layer;
|
|
||||||
|
|
||||||
// rendering a backing store requires a node be laid out
|
|
||||||
[layer setNeedsLayout];
|
|
||||||
[layer layoutIfNeeded];
|
|
||||||
|
|
||||||
if (layer.contents) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
[layer setNeedsDisplay];
|
|
||||||
[layer displayIfNeeded];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)recursivelyDisplay
|
|
||||||
{
|
|
||||||
if (![self __shouldLoadViewOrLayer]) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (ASDisplayNode *node in self.subnodes) {
|
|
||||||
[node recursivelyDisplay];
|
|
||||||
}
|
|
||||||
|
|
||||||
[self display];
|
|
||||||
}
|
|
||||||
|
|
||||||
@end
|
|
||||||
|
|
||||||
@interface ASRangeController () {
|
@interface ASRangeController () {
|
||||||
NSSet *_workingRangeIndexPaths;
|
BOOL _rangeIsValid;
|
||||||
NSSet *_workingRangeNodes;
|
|
||||||
BOOL _workingRangeIsValid;
|
// keys should be ASLayoutRangeTypes and values NSSets containing NSIndexPaths
|
||||||
|
NSMutableDictionary *_rangeTypeIndexPaths;
|
||||||
|
NSDictionary *_rangeTypeDelegates;
|
||||||
BOOL _queuedRangeUpdate;
|
BOOL _queuedRangeUpdate;
|
||||||
|
|
||||||
ASScrollDirection _scrollDirection;
|
ASScrollDirection _scrollDirection;
|
||||||
@@ -79,63 +33,32 @@
|
|||||||
- (instancetype)init {
|
- (instancetype)init {
|
||||||
if (self = [super init]) {
|
if (self = [super init]) {
|
||||||
|
|
||||||
_workingRangeIndexPaths = [NSSet set];
|
_rangeIsValid = YES;
|
||||||
_workingRangeIsValid = YES;
|
_rangeTypeIndexPaths = [[NSMutableDictionary alloc] init];
|
||||||
|
|
||||||
|
_rangeTypeDelegates = @{
|
||||||
|
@(ASLayoutRangeTypeRender): [[ASRenderRangeDelegate alloc] init],
|
||||||
|
@(ASLayoutRangeTypePreload): [[ASPreloadRangeDelegate alloc] init],
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma mark - View manipulation.
|
|
||||||
|
|
||||||
- (void)discardNode:(ASCellNode *)node
|
#pragma mark - View manipulation
|
||||||
{
|
|
||||||
ASDisplayNodeAssertMainThread();
|
|
||||||
ASDisplayNodeAssert(node, @"invalid argument");
|
|
||||||
|
|
||||||
if ([_workingRangeNodes containsObject:node]) {
|
|
||||||
// move the node's view to the working range area, so its rendering persists
|
|
||||||
[self addNodeToWorkingRange:node];
|
|
||||||
} else {
|
|
||||||
// this node isn't in the working range, remove it from the view hierarchy
|
|
||||||
[self removeNodeFromWorkingRange:node];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)removeNodeFromWorkingRange:(ASCellNode *)node
|
|
||||||
{
|
|
||||||
ASDisplayNodeAssertMainThread();
|
|
||||||
ASDisplayNodeAssert(node, @"invalid argument");
|
|
||||||
|
|
||||||
[node recursivelySetDisplaySuspended:YES];
|
|
||||||
[node.view removeFromSuperview];
|
|
||||||
|
|
||||||
// since this class usually manages large or infinite data sets, the working range
|
|
||||||
// directly bounds memory usage by requiring redrawing any content that falls outside the range.
|
|
||||||
[node recursivelyReclaimMemory];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)addNodeToWorkingRange:(ASCellNode *)node
|
|
||||||
{
|
|
||||||
ASDisplayNodeAssertMainThread();
|
|
||||||
ASDisplayNodeAssert(node, @"invalid argument");
|
|
||||||
|
|
||||||
// if node is in the working range it should not actively be in view
|
|
||||||
[node.view removeFromSuperview];
|
|
||||||
|
|
||||||
[node recursivelyDisplay];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)moveNode:(ASCellNode *)node toView:(UIView *)view
|
- (void)moveNode:(ASCellNode *)node toView:(UIView *)view
|
||||||
{
|
{
|
||||||
ASDisplayNodeAssertMainThread();
|
ASDisplayNodeAssertMainThread();
|
||||||
ASDisplayNodeAssert(node && view, @"invalid argument, did you mean -removeNodeFromWorkingRange:?");
|
ASDisplayNodeAssert(node, @"Cannot move a nil node to a view");
|
||||||
|
ASDisplayNodeAssert(view, @"Cannot move a node to a non-existent view");
|
||||||
|
|
||||||
[view addSubview:node.view];
|
[view addSubview:node.view];
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma mark -
|
|
||||||
#pragma mark API.
|
#pragma mark - API
|
||||||
|
|
||||||
- (void)visibleNodeIndexPathsDidChangeWithScrollDirection:(ASScrollDirection)scrollDirection
|
- (void)visibleNodeIndexPathsDidChangeWithScrollDirection:(ASScrollDirection)scrollDirection
|
||||||
{
|
{
|
||||||
@@ -159,42 +82,64 @@
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
NSArray *indexPaths = [_delegate rangeControllerVisibleNodeIndexPaths:self];
|
NSArray *visibleNodePaths = [_delegate rangeControllerVisibleNodeIndexPaths:self];
|
||||||
|
NSSet *visibleNodePathsSet = [NSSet setWithArray:visibleNodePaths];
|
||||||
CGSize viewportSize = [_delegate rangeControllerViewportSize:self];
|
CGSize viewportSize = [_delegate rangeControllerViewportSize:self];
|
||||||
|
|
||||||
if ([_layoutController shouldUpdateForVisibleIndexPaths:indexPaths viewportSize:viewportSize range:ASLayoutRangeRender]) {
|
// the layout controller needs to know what the current visible indices are to calculate range offsets
|
||||||
[_layoutController setVisibleNodeIndexPaths:indexPaths];
|
[_layoutController setVisibleNodeIndexPaths:visibleNodePaths];
|
||||||
NSSet *workingRangeIndexPaths = [_layoutController indexPathsForScrolling:_scrollDirection viewportSize:viewportSize range:ASLayoutRangeRender];
|
|
||||||
NSSet *visibleRangeIndexPaths = [NSSet setWithArray:indexPaths];
|
|
||||||
|
|
||||||
NSMutableSet *removedIndexPaths = _workingRangeIsValid ? [_workingRangeIndexPaths mutableCopy] : [NSMutableSet set];
|
for (NSInteger i = 0; i < ASLayoutRangeTypeCount; i++) {
|
||||||
[removedIndexPaths minusSet:workingRangeIndexPaths];
|
ASLayoutRangeType rangeType = (ASLayoutRangeType)i;
|
||||||
[removedIndexPaths minusSet:visibleRangeIndexPaths];
|
id rangeKey = @(rangeType);
|
||||||
if (removedIndexPaths.count) {
|
|
||||||
NSArray *removedNodes = [_delegate rangeController:self nodesAtIndexPaths:[removedIndexPaths allObjects]];
|
// this delegate decide what happens when a node is added or removed from a range
|
||||||
[removedNodes enumerateObjectsUsingBlock:^(ASCellNode *node, NSUInteger idx, BOOL *stop) {
|
id<ASRangeDelegate> rangeDelegate = _rangeTypeDelegates[rangeKey];
|
||||||
[self removeNodeFromWorkingRange:node];
|
|
||||||
}];
|
if ([_layoutController shouldUpdateForVisibleIndexPaths:visibleNodePaths viewportSize:viewportSize rangeType:rangeType]) {
|
||||||
|
NSSet *indexPaths = [_layoutController indexPathsForScrolling:_scrollDirection viewportSize:viewportSize rangeType:rangeType];
|
||||||
|
|
||||||
|
// Notify to remove indexpaths that are leftover that are not visible or included in the _layoutController calculated paths
|
||||||
|
NSMutableSet *removedIndexPaths = _rangeIsValid ? [[_rangeTypeIndexPaths objectForKey:rangeKey] mutableCopy] : [NSMutableSet set];
|
||||||
|
[removedIndexPaths minusSet:indexPaths];
|
||||||
|
[removedIndexPaths minusSet:visibleNodePathsSet];
|
||||||
|
if (removedIndexPaths.count) {
|
||||||
|
NSArray *removedNodes = [_delegate rangeController:self nodesAtIndexPaths:[removedIndexPaths allObjects]];
|
||||||
|
[removedNodes enumerateObjectsUsingBlock:^(ASCellNode *node, NSUInteger idx, BOOL *stop) {
|
||||||
|
[rangeDelegate node:node exitedRangeType:rangeType];
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Notify to add indexpaths that are not currently in _rangeTypeIndexPaths
|
||||||
|
NSMutableSet *addedIndexPaths = [indexPaths mutableCopy];
|
||||||
|
[addedIndexPaths minusSet:[_rangeTypeIndexPaths objectForKey:rangeKey]];
|
||||||
|
|
||||||
|
// The preload range (for example) should include nodes that are visible
|
||||||
|
if ([self shouldRemoveVisibleNodesFromRangeType:rangeType]) {
|
||||||
|
[addedIndexPaths minusSet:visibleNodePathsSet];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (addedIndexPaths.count) {
|
||||||
|
NSArray *addedNodes = [_delegate rangeController:self nodesAtIndexPaths:[addedIndexPaths allObjects]];
|
||||||
|
[addedNodes enumerateObjectsUsingBlock:^(ASCellNode *node, NSUInteger idx, BOOL *stop) {
|
||||||
|
[rangeDelegate node:node enteredRangeType:rangeType];
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
|
||||||
|
// set the range indexpaths so that we can remove/add on the next update pass
|
||||||
|
[_rangeTypeIndexPaths setObject:indexPaths forKey:rangeKey];
|
||||||
}
|
}
|
||||||
|
|
||||||
NSMutableSet *addedIndexPaths = [workingRangeIndexPaths mutableCopy];
|
|
||||||
[addedIndexPaths minusSet:_workingRangeIndexPaths];
|
|
||||||
[addedIndexPaths minusSet:visibleRangeIndexPaths];
|
|
||||||
if (addedIndexPaths.count) {
|
|
||||||
NSArray *addedNodes = [_delegate rangeController:self nodesAtIndexPaths:[addedIndexPaths allObjects]];
|
|
||||||
[addedNodes enumerateObjectsUsingBlock:^(ASCellNode *node, NSUInteger idx, BOOL *stop) {
|
|
||||||
[self addNodeToWorkingRange:node];
|
|
||||||
}];
|
|
||||||
}
|
|
||||||
|
|
||||||
_workingRangeIndexPaths = workingRangeIndexPaths;
|
|
||||||
_workingRangeNodes = [NSSet setWithArray:[_delegate rangeController:self nodesAtIndexPaths:[workingRangeIndexPaths allObjects]]];
|
|
||||||
_workingRangeIsValid = YES;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_rangeIsValid = YES;
|
||||||
_queuedRangeUpdate = NO;
|
_queuedRangeUpdate = NO;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (BOOL)shouldRemoveVisibleNodesFromRangeType:(ASLayoutRangeType)rangeType
|
||||||
|
{
|
||||||
|
return rangeType != ASLayoutRangeTypePreload;
|
||||||
|
}
|
||||||
|
|
||||||
- (void)configureContentView:(UIView *)contentView forCellNode:(ASCellNode *)cellNode
|
- (void)configureContentView:(UIView *)contentView forCellNode:(ASCellNode *)cellNode
|
||||||
{
|
{
|
||||||
[cellNode recursivelySetDisplaySuspended:NO];
|
[cellNode recursivelySetDisplaySuspended:NO];
|
||||||
@@ -204,21 +149,15 @@
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// clean the content view
|
||||||
for (UIView *view in contentView.subviews) {
|
for (UIView *view in contentView.subviews) {
|
||||||
ASDisplayNode *node = view.asyncdisplaykit_node;
|
[view removeFromSuperview];
|
||||||
if (node) {
|
|
||||||
// plunk this node back into the working range, if appropriate
|
|
||||||
ASDisplayNodeAssert([node isKindOfClass:[ASCellNode class]], @"invalid node");
|
|
||||||
[self discardNode:(ASCellNode *)node];
|
|
||||||
} else {
|
|
||||||
// if it's not a node, it's something random UITableView added to the hierarchy. kill it.
|
|
||||||
[view removeFromSuperview];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[self moveNode:cellNode toView:contentView];
|
[self moveNode:cellNode toView:contentView];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#pragma mark - ASDataControllerDelegete
|
#pragma mark - ASDataControllerDelegete
|
||||||
|
|
||||||
- (void)dataControllerBeginUpdates:(ASDataController *)dataController {
|
- (void)dataControllerBeginUpdates:(ASDataController *)dataController {
|
||||||
@@ -252,7 +191,7 @@
|
|||||||
ASDisplayNodePerformBlockOnMainThread(^{
|
ASDisplayNodePerformBlockOnMainThread(^{
|
||||||
[_layoutController insertNodesAtIndexPaths:indexPaths withSizes:nodeSizes];
|
[_layoutController insertNodesAtIndexPaths:indexPaths withSizes:nodeSizes];
|
||||||
[_delegate rangeController:self didInsertNodesAtIndexPaths:indexPaths withAnimationOption:animationOption];
|
[_delegate rangeController:self didInsertNodesAtIndexPaths:indexPaths withAnimationOption:animationOption];
|
||||||
_workingRangeIsValid = NO;
|
_rangeIsValid = NO;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -268,7 +207,7 @@
|
|||||||
ASDisplayNodePerformBlockOnMainThread(^{
|
ASDisplayNodePerformBlockOnMainThread(^{
|
||||||
[_layoutController deleteNodesAtIndexPaths:indexPaths];
|
[_layoutController deleteNodesAtIndexPaths:indexPaths];
|
||||||
[_delegate rangeController:self didDeleteNodesAtIndexPaths:indexPaths withAnimationOption:animationOption];
|
[_delegate rangeController:self didDeleteNodesAtIndexPaths:indexPaths withAnimationOption:animationOption];
|
||||||
_workingRangeIsValid = NO;
|
_rangeIsValid = NO;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -296,7 +235,7 @@
|
|||||||
ASDisplayNodePerformBlockOnMainThread(^{
|
ASDisplayNodePerformBlockOnMainThread(^{
|
||||||
[_layoutController insertSections:sectionNodeSizes atIndexSet:indexSet];
|
[_layoutController insertSections:sectionNodeSizes atIndexSet:indexSet];
|
||||||
[_delegate rangeController:self didInsertSectionsAtIndexSet:indexSet withAnimationOption:animationOption];
|
[_delegate rangeController:self didInsertSectionsAtIndexSet:indexSet withAnimationOption:animationOption];
|
||||||
_workingRangeIsValid = NO;
|
_rangeIsValid = NO;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -312,7 +251,7 @@
|
|||||||
ASDisplayNodePerformBlockOnMainThread(^{
|
ASDisplayNodePerformBlockOnMainThread(^{
|
||||||
[_layoutController deleteSectionsAtIndexSet:indexSet];
|
[_layoutController deleteSectionsAtIndexSet:indexSet];
|
||||||
[_delegate rangeController:self didDeleteSectionsAtIndexSet:indexSet withAnimationOption:animationOption];
|
[_delegate rangeController:self didDeleteSectionsAtIndexSet:indexSet withAnimationOption:animationOption];
|
||||||
_workingRangeIsValid = NO;
|
_rangeIsValid = NO;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
22
AsyncDisplayKit/Details/ASRangeDelegate.h
Normal file
22
AsyncDisplayKit/Details/ASRangeDelegate.h
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
/* Copyright (c) 2014-present, Facebook, Inc.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the BSD-style license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#import <Foundation/Foundation.h>
|
||||||
|
|
||||||
|
#import <AsyncDisplayKit/ASLayoutRangeType.h>
|
||||||
|
|
||||||
|
@class ASDisplayNode;
|
||||||
|
|
||||||
|
@protocol ASRangeDelegate <NSObject>
|
||||||
|
|
||||||
|
@required
|
||||||
|
|
||||||
|
- (void)node:(ASDisplayNode *)node enteredRangeType:(ASLayoutRangeType)rangeType;
|
||||||
|
- (void)node:(ASDisplayNode *)node exitedRangeType:(ASLayoutRangeType)rangeType;
|
||||||
|
|
||||||
|
@end
|
||||||
15
AsyncDisplayKit/Details/ASRenderRangeDelegate.h
Normal file
15
AsyncDisplayKit/Details/ASRenderRangeDelegate.h
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
/* Copyright (c) 2014-present, Facebook, Inc.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the BSD-style license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#import <Foundation/Foundation.h>
|
||||||
|
|
||||||
|
#import <AsyncDisplayKit/ASRangeDelegate.h>
|
||||||
|
|
||||||
|
@interface ASRenderRangeDelegate : NSObject
|
||||||
|
|
||||||
|
@end
|
||||||
88
AsyncDisplayKit/Details/ASRenderRangeDelegate.mm
Normal file
88
AsyncDisplayKit/Details/ASRenderRangeDelegate.mm
Normal file
@@ -0,0 +1,88 @@
|
|||||||
|
/* Copyright (c) 2014-present, Facebook, Inc.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the BSD-style license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#import "ASRenderRangeDelegate.h"
|
||||||
|
|
||||||
|
#import "ASDisplayNode.h"
|
||||||
|
#import "ASDisplayNode+Subclasses.h"
|
||||||
|
#import "ASDisplayNodeInternal.h"
|
||||||
|
|
||||||
|
@interface ASDisplayNode (ASRenderRangeDelegate)
|
||||||
|
|
||||||
|
- (void)display;
|
||||||
|
- (void)recursivelyDisplay;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation ASDisplayNode (ASRenderRangeDelegate)
|
||||||
|
|
||||||
|
- (void)display
|
||||||
|
{
|
||||||
|
if (![self __shouldLoadViewOrLayer]) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ASDisplayNodeAssertMainThread();
|
||||||
|
ASDisplayNodeAssert(self.nodeLoaded, @"backing store must be loaded before calling -display");
|
||||||
|
|
||||||
|
CALayer *layer = self.layer;
|
||||||
|
|
||||||
|
// rendering a backing store requires a node be laid out
|
||||||
|
[layer setNeedsLayout];
|
||||||
|
[layer layoutIfNeeded];
|
||||||
|
|
||||||
|
if (layer.contents) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
[layer setNeedsDisplay];
|
||||||
|
[layer displayIfNeeded];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)recursivelyDisplay
|
||||||
|
{
|
||||||
|
if (![self __shouldLoadViewOrLayer]) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (ASDisplayNode *node in self.subnodes) {
|
||||||
|
[node recursivelyDisplay];
|
||||||
|
}
|
||||||
|
|
||||||
|
[self display];
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation ASRenderRangeDelegate
|
||||||
|
|
||||||
|
- (void)node:(ASDisplayNode *)node enteredRangeType:(ASLayoutRangeType)rangeType
|
||||||
|
{
|
||||||
|
ASDisplayNodeAssertMainThread();
|
||||||
|
ASDisplayNodeAssert(node, @"invalid argument");
|
||||||
|
|
||||||
|
// if node is in the working range it should not actively be in view
|
||||||
|
[node.view removeFromSuperview];
|
||||||
|
|
||||||
|
[node recursivelyDisplay];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)node:(ASDisplayNode *)node exitedRangeType:(ASLayoutRangeType)rangeType
|
||||||
|
{
|
||||||
|
ASDisplayNodeAssertMainThread();
|
||||||
|
ASDisplayNodeAssert(node, @"invalid argument");
|
||||||
|
|
||||||
|
[node recursivelySetDisplaySuspended:YES];
|
||||||
|
[node.view removeFromSuperview];
|
||||||
|
|
||||||
|
// since this class usually manages large or infinite data sets, the working range
|
||||||
|
// directly bounds memory usage by requiring redrawing any content that falls outside the range.
|
||||||
|
[node recursivelyClearRendering];
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
@@ -17,7 +17,7 @@
|
|||||||
#import "BlurbNode.h"
|
#import "BlurbNode.h"
|
||||||
#import "KittenNode.h"
|
#import "KittenNode.h"
|
||||||
|
|
||||||
static const NSInteger kLitterSize = 20;
|
static const NSInteger kLitterSize = 200;
|
||||||
|
|
||||||
|
|
||||||
@interface ViewController () <ASTableViewDataSource, ASTableViewDelegate>
|
@interface ViewController () <ASTableViewDataSource, ASTableViewDelegate>
|
||||||
|
|||||||
Reference in New Issue
Block a user