From 52a34db88475529a40a3fb70c51856ede1cf2545 Mon Sep 17 00:00:00 2001 From: Michael Schneider Date: Thu, 30 Jun 2016 07:44:00 -0700 Subject: [PATCH] Add pending state for range mode in ASTableNode and ASCollectionNode --- AsyncDisplayKit/ASCollectionNode.h | 4 +- AsyncDisplayKit/ASCollectionNode.mm | 159 +++++++++++------- AsyncDisplayKit/ASTableNode.h | 2 +- AsyncDisplayKit/ASTableNode.mm | 88 ++++++---- .../Details/ASAbstractLayoutController.mm | 6 +- 5 files changed, 163 insertions(+), 96 deletions(-) diff --git a/AsyncDisplayKit/ASCollectionNode.h b/AsyncDisplayKit/ASCollectionNode.h index b65c79a2..c28eae09 100644 --- a/AsyncDisplayKit/ASCollectionNode.h +++ b/AsyncDisplayKit/ASCollectionNode.h @@ -25,11 +25,11 @@ NS_ASSUME_NONNULL_BEGIN - (instancetype)initWithCollectionViewLayout:(UICollectionViewLayout *)layout; - (instancetype)initWithFrame:(CGRect)frame collectionViewLayout:(UICollectionViewLayout *)layout; +@property (strong, nonatomic, readonly) ASCollectionView *view; + @property (weak, nonatomic) id delegate; @property (weak, nonatomic) id dataSource; -@property (nonatomic, readonly) ASCollectionView *view; - /** * Tuning parameters for a range type in full mode. * diff --git a/AsyncDisplayKit/ASCollectionNode.mm b/AsyncDisplayKit/ASCollectionNode.mm index 2784c9a9..876429c3 100644 --- a/AsyncDisplayKit/ASCollectionNode.mm +++ b/AsyncDisplayKit/ASCollectionNode.mm @@ -12,52 +12,76 @@ #import "ASCollectionNode.h" #import "ASCollectionInternal.h" -#import "ASCollectionViewLayoutFacilitatorProtocol.h" #import "ASDisplayNode+Subclasses.h" #import "ASEnvironmentInternal.h" #import "ASInternalHelpers.h" #import "ASRangeControllerUpdateRangeProtocol+Beta.h" + #include +#pragma mark - _ASCollectionPendingState + @interface _ASCollectionPendingState : NSObject @property (weak, nonatomic) id delegate; @property (weak, nonatomic) id dataSource; +@property (assign, nonatomic) ASLayoutRangeMode rangeMode; @end @implementation _ASCollectionPendingState -@end -#if 0 // This is not used yet, but will provide a way to avoid creating the view to set range values. -@implementation _ASCollectionPendingState +- (instancetype)init { - std::vector _tuningParameters; + self = [super init]; + if (self) { + _rangeMode = ASLayoutRangeModeCount; + } + return self; +} +@end + +// TODO: Add support for tuning parameters in the pending state +#if 0 // This is not used yet, but will provide a way to avoid creating the view to set range values. +@implementation _ASCollectionPendingState { + std::vector> _tuningParameters; } - (instancetype)init { - if (!(self = [super init])) { - return nil; + self = [super init]; + if (self) { + _tuningParameters = std::vector> (ASLayoutRangeModeCount, std::vector (ASLayoutRangeTypeCount)); + _rangeMode = ASLayoutRangeModeCount; } - _tuningParameters = std::vector(ASLayoutRangeTypeCount); return self; } - (ASRangeTuningParameters)tuningParametersForRangeType:(ASLayoutRangeType)rangeType { - ASDisplayNodeAssert(rangeType < _tuningParameters.size(), @"Requesting a range that is OOB for the configured tuning parameters"); - return _tuningParameters[rangeType]; + return [self tuningParametersForRangeMode:ASLayoutRangeModeFull rangeType:rangeType]; } - (void)setTuningParameters:(ASRangeTuningParameters)tuningParameters forRangeType:(ASLayoutRangeType)rangeType { - ASDisplayNodeAssert(rangeType < _tuningParameters.size(), @"Requesting a range that is OOB for the configured tuning parameters"); - ASDisplayNodeAssert(rangeType != ASLayoutRangeTypeVisible, @"Must not set Visible range tuning parameters (always 0, 0)"); - _tuningParameters[rangeType] = tuningParameters; + return [self setTuningParameters:tuningParameters forRangeMode:ASLayoutRangeModeFull rangeType:rangeType]; +} + +- (ASRangeTuningParameters)tuningParametersForRangeMode:(ASLayoutRangeMode)rangeMode rangeType:(ASLayoutRangeType)rangeType +{ + ASDisplayNodeAssert(rangeMode < _tuningParameters.size() && rangeType < _tuningParameters[rangeMode].size(), @"Requesting a range that is OOB for the configured tuning parameters"); + return _tuningParameters[rangeMode][rangeType]; +} + +- (void)setTuningParameters:(ASRangeTuningParameters)tuningParameters forRangeMode:(ASLayoutRangeMode)rangeMode rangeType:(ASLayoutRangeType)rangeType +{ + ASDisplayNodeAssert(rangeMode < _tuningParameters.size() && rangeType < _tuningParameters[rangeMode].size(), @"Setting a range that is OOB for the configured tuning parameters"); + _tuningParameters[rangeMode][rangeType] = tuningParameters; } @end #endif +#pragma mark - ASCollectionNode + @interface ASCollectionNode () { ASDN::RecursiveMutex _environmentStateLock; @@ -67,6 +91,8 @@ @implementation ASCollectionNode +#pragma mark Lifecycle + - (instancetype)init { ASDISPLAYNODE_NOT_DESIGNATED_INITIALIZER(); @@ -109,6 +135,8 @@ return nil; } +#pragma mark ASDisplayNode + - (void)didLoad { [super didLoad]; @@ -121,9 +149,39 @@ self.pendingState = nil; view.asyncDelegate = pendingState.delegate; view.asyncDataSource = pendingState.dataSource; + if (pendingState.rangeMode != ASLayoutRangeModeCount) { + [view.rangeController updateCurrentRangeWithMode:pendingState.rangeMode]; + } } } +- (ASCollectionView *)view +{ + return (ASCollectionView *)[super view]; +} + +- (void)clearContents +{ + [super clearContents]; + [self.view clearContents]; +} + +- (void)clearFetchedData +{ + [super clearFetchedData]; + [self.view clearFetchedData]; +} + +#if ASRangeControllerLoggingEnabled +- (void)visibleStateDidChange:(BOOL)isVisible +{ + [super visibleStateDidChange:isVisible]; + NSLog(@"%@ - visible: %d", self, isVisible); +} +#endif + +#pragma mark Setter / Getter + - (_ASCollectionPendingState *)pendingState { if (!_pendingState && ![self isNodeLoaded]) { @@ -171,47 +229,7 @@ } } -- (ASCollectionView *)view -{ - return (ASCollectionView *)[super view]; -} - -#if ASRangeControllerLoggingEnabled -- (void)visibleStateDidChange:(BOOL)isVisible -{ - [super visibleStateDidChange:isVisible]; - NSLog(@"%@ - visible: %d", self, isVisible); -} -#endif - -- (void)clearContents -{ - [super clearContents]; - [self.view clearContents]; -} - -- (void)clearFetchedData -{ - [super clearFetchedData]; - [self.view clearFetchedData]; -} - -- (void)beginUpdates -{ - [self.view.dataController beginUpdates]; -} - -- (void)endUpdatesAnimated:(BOOL)animated -{ - [self endUpdatesAnimated:animated completion:nil]; -} - -- (void)endUpdatesAnimated:(BOOL)animated completion:(void (^)(BOOL))completion -{ - [self.view.dataController endUpdatesAnimated:animated completion:completion]; -} - -#pragma mark - ASCollectionView Forwards +#pragma mark ASCollectionView Forwards - (ASRangeTuningParameters)tuningParametersForRangeType:(ASLayoutRangeType)rangeType { @@ -233,11 +251,6 @@ 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]; @@ -253,6 +266,34 @@ [self.view reloadDataImmediately]; } +- (void)beginUpdates +{ + [self.view.dataController beginUpdates]; +} + +- (void)endUpdatesAnimated:(BOOL)animated +{ + [self endUpdatesAnimated:animated completion:nil]; +} + +- (void)endUpdatesAnimated:(BOOL)animated completion:(void (^)(BOOL))completion +{ + [self.view.dataController endUpdatesAnimated:animated completion:completion]; +} + +#pragma mark - ASRangeControllerUpdateRangeProtocol + +- (void)updateCurrentRangeWithMode:(ASLayoutRangeMode)rangeMode; +{ + if ([self pendingState]) { + _pendingState.rangeMode = rangeMode; + } else { + [self.view.rangeController updateCurrentRangeWithMode:rangeMode]; + } +} + +#pragma mark ASEnvironment + ASEnvironmentCollectionTableSetEnvironmentState(_environmentStateLock) @end diff --git a/AsyncDisplayKit/ASTableNode.h b/AsyncDisplayKit/ASTableNode.h index 795e2ef9..4139f36f 100644 --- a/AsyncDisplayKit/ASTableNode.h +++ b/AsyncDisplayKit/ASTableNode.h @@ -21,7 +21,7 @@ - (instancetype)init; // UITableViewStylePlain - (instancetype)initWithStyle:(UITableViewStyle)style; -@property (nonatomic, readonly) ASTableView *view; +@property (strong, nonatomic, readonly) ASTableView *view; // These properties can be set without triggering the view to be created, so it's fine to set them in -init. @property (weak, nonatomic) id delegate; diff --git a/AsyncDisplayKit/ASTableNode.mm b/AsyncDisplayKit/ASTableNode.mm index e5b09fea..191eba63 100644 --- a/AsyncDisplayKit/ASTableNode.mm +++ b/AsyncDisplayKit/ASTableNode.mm @@ -10,21 +10,35 @@ // of patent rights can be found in the PATENTS file in the same directory. // +#import "ASTableNode.h" +#import "ASTableViewInternal.h" #import "ASEnvironmentInternal.h" #import "ASDisplayNode+Subclasses.h" -#import "ASFlowLayoutController.h" #import "ASInternalHelpers.h" #import "ASRangeControllerUpdateRangeProtocol+Beta.h" -#import "ASTableViewInternal.h" + +#pragma mark - _ASTablePendingState @interface _ASTablePendingState : NSObject @property (weak, nonatomic) id delegate; @property (weak, nonatomic) id dataSource; +@property (assign, nonatomic) ASLayoutRangeMode rangeMode; @end @implementation _ASTablePendingState +- (instancetype)init +{ + self = [super init]; + if (self) { + _rangeMode = ASLayoutRangeModeCount; + } + return self; +} + @end +#pragma mark - ASTableView + @interface ASTableNode () { ASDN::RecursiveMutex _environmentStateLock; @@ -39,6 +53,8 @@ @implementation ASTableNode +#pragma mark Lifecycle + - (instancetype)_initWithTableView:(ASTableView *)tableView { // Avoid a retain cycle. In this case, the ASTableView is creating us, and strongly retains us. @@ -72,6 +88,8 @@ return [self _initWithFrame:CGRectZero style:UITableViewStylePlain dataControllerClass:nil]; } +#pragma mark ASDisplayNode + - (void)didLoad { [super didLoad]; @@ -84,22 +102,43 @@ self.pendingState = nil; view.asyncDelegate = pendingState.delegate; view.asyncDataSource = pendingState.dataSource; + if (pendingState.rangeMode != ASLayoutRangeModeCount) { + [view.rangeController updateCurrentRangeWithMode:pendingState.rangeMode]; + } } } -- (void)updateCurrentRangeWithMode:(ASLayoutRangeMode)rangeMode +- (ASTableView *)view { - if (!self.isNodeLoaded) { - return; - } - - [self.view.rangeController updateCurrentRangeWithMode:rangeMode]; + return (ASTableView *)[super view]; } +- (void)clearContents +{ + [super clearContents]; + [self.view clearContents]; +} + +- (void)clearFetchedData +{ + [super clearFetchedData]; + [self.view clearFetchedData]; +} + +#if ASRangeControllerLoggingEnabled +- (void)visibleStateDidChange:(BOOL)isVisible +{ + [super visibleStateDidChange:isVisible]; + NSLog(@"%@ - visible: %d", self, isVisible); +} +#endif + +#pragma mark Setter / Getter + - (_ASTablePendingState *)pendingState { if (!_pendingState && ![self isNodeLoaded]) { - self.pendingState = [[_ASTablePendingState alloc] init]; + _pendingState = [[_ASTablePendingState alloc] init]; } ASDisplayNodeAssert(![self isNodeLoaded] || !_pendingState, @"ASTableNode should not have a pendingState once it is loaded"); return _pendingState; @@ -143,30 +182,19 @@ } } -- (ASTableView *)view +#pragma mark ASRangeControllerUpdateRangeProtocol + +- (void)updateCurrentRangeWithMode:(ASLayoutRangeMode)rangeMode { - return (ASTableView *)[super view]; + if ([self pendingState]) { + _pendingState.rangeMode = rangeMode; + } else { + ASDisplayNodeAssert([self isNodeLoaded], @"ASTableNode should be loaded if pendingState doesn't exist"); + [self.view.rangeController updateCurrentRangeWithMode:rangeMode]; + } } -#if ASRangeControllerLoggingEnabled -- (void)visibleStateDidChange:(BOOL)isVisible -{ - [super visibleStateDidChange:isVisible]; - NSLog(@"%@ - visible: %d", self, isVisible); -} -#endif - -- (void)clearContents -{ - [super clearContents]; - [self.view clearContents]; -} - -- (void)clearFetchedData -{ - [super clearFetchedData]; - [self.view clearFetchedData]; -} +#pragma mark ASEnvironment ASEnvironmentCollectionTableSetEnvironmentState(_environmentStateLock) diff --git a/AsyncDisplayKit/Details/ASAbstractLayoutController.mm b/AsyncDisplayKit/Details/ASAbstractLayoutController.mm index 91121083..b0ef11b3 100644 --- a/AsyncDisplayKit/Details/ASAbstractLayoutController.mm +++ b/AsyncDisplayKit/Details/ASAbstractLayoutController.mm @@ -91,15 +91,13 @@ extern BOOL ASRangeTuningParametersEqualToRangeTuningParameters(ASRangeTuningPar - (ASRangeTuningParameters)tuningParametersForRangeMode:(ASLayoutRangeMode)rangeMode rangeType:(ASLayoutRangeType)rangeType { - ASDisplayNodeAssert(rangeMode < _tuningParameters.size() && rangeType < _tuningParameters[rangeMode].size(), - @"Requesting a range that is OOB for the configured tuning parameters"); + ASDisplayNodeAssert(rangeMode < _tuningParameters.size() && rangeType < _tuningParameters[rangeMode].size(), @"Requesting a range that is OOB for the configured tuning parameters"); return _tuningParameters[rangeMode][rangeType]; } - (void)setTuningParameters:(ASRangeTuningParameters)tuningParameters forRangeMode:(ASLayoutRangeMode)rangeMode rangeType:(ASLayoutRangeType)rangeType { - ASDisplayNodeAssert(rangeMode < _tuningParameters.size() && rangeType < _tuningParameters[rangeMode].size(), - @"Setting a range that is OOB for the configured tuning parameters"); + ASDisplayNodeAssert(rangeMode < _tuningParameters.size() && rangeType < _tuningParameters[rangeMode].size(), @"Setting a range that is OOB for the configured tuning parameters"); _tuningParameters[rangeMode][rangeType] = tuningParameters; }