From 60889f555ea5e7c9d55d394fdb55f7702f4ee139 Mon Sep 17 00:00:00 2001 From: Michael Schneider Date: Fri, 26 Feb 2016 20:20:13 -0800 Subject: [PATCH] Add API to update the current range mode of a table or collection view range controller --- AsyncDisplayKit/ASCollectionNode.h | 3 ++- AsyncDisplayKit/ASCollectionNode.mm | 5 +++++ AsyncDisplayKit/ASTableNode.h | 4 +++- AsyncDisplayKit/ASTableNode.m | 5 +++++ AsyncDisplayKit/ASTableViewInternal.h | 1 + AsyncDisplayKit/Details/ASRangeController.h | 14 ++++++++++++++ AsyncDisplayKit/Details/ASRangeController.mm | 15 ++++++++++++--- 7 files changed, 42 insertions(+), 5 deletions(-) diff --git a/AsyncDisplayKit/ASCollectionNode.h b/AsyncDisplayKit/ASCollectionNode.h index 49ca3ffe5a..1b99fecb5d 100644 --- a/AsyncDisplayKit/ASCollectionNode.h +++ b/AsyncDisplayKit/ASCollectionNode.h @@ -9,6 +9,7 @@ #import @protocol ASCollectionViewLayoutFacilitatorProtocol; +@protocol ASRangeControllerUpdateRangeProtocol; NS_ASSUME_NONNULL_BEGIN @@ -16,7 +17,7 @@ NS_ASSUME_NONNULL_BEGIN * ASCollectionNode is a node based class that wraps an ASCollectionView. It can be used * as a subnode of another node, and provide room for many (great) features and improvements later on. */ -@interface ASCollectionNode : ASDisplayNode +@interface ASCollectionNode : ASDisplayNode - (instancetype)initWithCollectionViewLayout:(UICollectionViewLayout *)layout; - (instancetype)initWithFrame:(CGRect)frame collectionViewLayout:(UICollectionViewLayout *)layout; diff --git a/AsyncDisplayKit/ASCollectionNode.mm b/AsyncDisplayKit/ASCollectionNode.mm index 68e7d9a341..be5d0cceff 100644 --- a/AsyncDisplayKit/ASCollectionNode.mm +++ b/AsyncDisplayKit/ASCollectionNode.mm @@ -219,6 +219,11 @@ return [self.view.rangeController setTuningParameters:tuningParameters forRangeMode:rangeMode rangeType:rangeType]; } +- (void)updateCurrentRangeWithMode:(ASLayoutRangeMode)rangeMode; +{ + [self.view.rangeController updateCurrentRangeWithMode:rangeMode]; +} + - (void)reloadDataWithCompletion:(void (^)())completion { [self.view reloadDataWithCompletion:completion]; diff --git a/AsyncDisplayKit/ASTableNode.h b/AsyncDisplayKit/ASTableNode.h index 13d5c88fa8..dfedb2db11 100644 --- a/AsyncDisplayKit/ASTableNode.h +++ b/AsyncDisplayKit/ASTableNode.h @@ -8,11 +8,13 @@ #import +@protocol ASRangeControllerUpdateRangeProtocol; + /** * ASTableNode is a node based class that wraps an ASTableView. It can be used * as a subnode of another node, and provide room for many (great) features and improvements later on. */ -@interface ASTableNode : ASDisplayNode +@interface ASTableNode : ASDisplayNode - (instancetype)init; // UITableViewStylePlain - (instancetype)initWithStyle:(UITableViewStyle)style; diff --git a/AsyncDisplayKit/ASTableNode.m b/AsyncDisplayKit/ASTableNode.m index a54f0bf11e..765e260262 100644 --- a/AsyncDisplayKit/ASTableNode.m +++ b/AsyncDisplayKit/ASTableNode.m @@ -77,6 +77,11 @@ } } +- (void)updateCurrentRangeWithMode:(ASLayoutRangeMode)rangeMode +{ + [self.view.rangeController updateCurrentRangeWithMode:rangeMode]; +} + - (_ASTablePendingState *)pendingState { if (!_pendingState && ![self isNodeLoaded]) { diff --git a/AsyncDisplayKit/ASTableViewInternal.h b/AsyncDisplayKit/ASTableViewInternal.h index cc93c44a84..e92a7b84e0 100644 --- a/AsyncDisplayKit/ASTableViewInternal.h +++ b/AsyncDisplayKit/ASTableViewInternal.h @@ -14,6 +14,7 @@ @property (nonatomic, retain, readonly) ASDataController *dataController; @property (nonatomic, weak, readwrite) ASTableNode *tableNode; +@property (nonatomic, strong, readonly) ASRangeController *rangeController; /** * Initializer. diff --git a/AsyncDisplayKit/Details/ASRangeController.h b/AsyncDisplayKit/Details/ASRangeController.h index d5288f40e2..30ac3ed1e1 100644 --- a/AsyncDisplayKit/Details/ASRangeController.h +++ b/AsyncDisplayKit/Details/ASRangeController.h @@ -11,6 +11,7 @@ #import #import #import +#import #define RangeControllerLoggingEnabled 0 @@ -44,6 +45,10 @@ NS_ASSUME_NONNULL_BEGIN */ - (void)visibleNodeIndexPathsDidChangeWithScrollDirection:(ASScrollDirection)scrollDirection; + +/// This is a way for a one way update of range with a given mode. +- (void)updateCurrentRangeWithMode:(ASLayoutRangeMode)rangeMode; + /** * Add the sized node for `indexPath` as a subview of `contentView`. * @@ -77,6 +82,15 @@ NS_ASSUME_NONNULL_BEGIN @end +@protocol ASRangeControllerUpdateRangeProtocol + +/** + * Updates the current range mode of the range controller for at least the next range update. + */ +- (void)updateCurrentRangeWithMode:(ASLayoutRangeMode)rangeMode; + +@end + /** * Data source for ASRangeController. * diff --git a/AsyncDisplayKit/Details/ASRangeController.mm b/AsyncDisplayKit/Details/ASRangeController.mm index 1b8d7d8f89..73b4e60841 100644 --- a/AsyncDisplayKit/Details/ASRangeController.mm +++ b/AsyncDisplayKit/Details/ASRangeController.mm @@ -67,6 +67,14 @@ - (void)visibleNodeIndexPathsDidChangeWithScrollDirection:(ASScrollDirection)scrollDirection { _scrollDirection = scrollDirection; + + [self scheduleRangeUpdate]; +} + +- (void)updateCurrentRangeWithMode:(ASLayoutRangeMode)rangeMode +{ + _currentRangeMode = rangeMode; + [self scheduleRangeUpdate]; } @@ -130,8 +138,7 @@ NSMutableOrderedSet *allIndexPaths = [[NSMutableOrderedSet alloc] initWithSet:visibleIndexPaths]; ASInterfaceState selfInterfaceState = [_dataSource interfaceStateForRangeController:self]; - ASLayoutRangeMode rangeMode = [ASRangeController rangeModeForInterfaceState:selfInterfaceState - currentRangeMode:_currentRangeMode]; + ASLayoutRangeMode rangeMode = (_currentRangeMode == ASLayoutRangeModeInvalid) ? ASLayoutRangeModeMinimum : _currentRangeMode; ASRangeTuningParameters parametersFetchData = [_layoutController tuningParametersForRangeMode:rangeMode rangeType:ASLayoutRangeTypeFetchData]; @@ -168,7 +175,9 @@ NSSet *allCurrentIndexPaths = [[allIndexPaths set] copy]; [allIndexPaths unionSet:_allPreviousIndexPaths]; _allPreviousIndexPaths = allCurrentIndexPaths; - _currentRangeMode = rangeMode; + + // Update the current range mode based on interface state + _currentRangeMode = [ASRangeController rangeModeForInterfaceState:selfInterfaceState currentRangeMode:_currentRangeMode]; if (!_rangeIsValid) { [allIndexPaths addObjectsFromArray:ASIndexPathsForMultidimensionalArray(allNodes)];