mirror of
https://github.com/HackPlan/AsyncDisplayKit.git
synced 2026-04-23 03:20:39 +08:00
Merge pull request #1921 from facebook/AHRangeModeUpdatingIssues
[ASRangeController] Fix Major Range Mode Updating Issues
This commit is contained in:
@@ -27,7 +27,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 <ASRangeControllerUpdateRangeProtocol>
|
||||
|
||||
- (instancetype)initWithCollectionViewLayout:(UICollectionViewLayout *)layout;
|
||||
- (instancetype)initWithFrame:(CGRect)frame collectionViewLayout:(UICollectionViewLayout *)layout;
|
||||
@@ -111,8 +111,4 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@end
|
||||
|
||||
@interface ASCollectionNode (ASRangeControllerUpdateRangeProtocol) <ASRangeControllerUpdateRangeProtocol>
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
//
|
||||
|
||||
#import "ASContextTransitioning.h"
|
||||
#import "ASLayoutRangeType.h"
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@@ -116,6 +117,15 @@ ASDISPLAYNODE_EXTERN_C_END
|
||||
*/
|
||||
- (void)hierarchyDisplayDidFinish;
|
||||
|
||||
/**
|
||||
* Only ASLayoutRangeModeVisibleOnly or ASLayoutRangeModeLowMemory are recommended. Default is ASLayoutRangeModeVisibleOnly,
|
||||
* because this is the only way to ensure an application will not have blank / flashing views as the user navigates back after
|
||||
* a memory warning. Apps that wish to use the more effective / aggressive ASLayoutRangeModeLowMemory may need to take steps
|
||||
* to mitigate this behavior, including: restoring a larger range mode to the next controller before the user navigates there,
|
||||
* enabling .neverShowPlaceholders on ASCellNodes so that the navigation operation is blocked on redisplay completing, etc.
|
||||
*/
|
||||
+ (void)setRangeModeForMemoryWarnings:(ASLayoutRangeMode)rangeMode;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
* 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 <ASRangeControllerUpdateRangeProtocol>
|
||||
|
||||
- (instancetype)init; // UITableViewStylePlain
|
||||
- (instancetype)initWithStyle:(UITableViewStyle)style;
|
||||
@@ -34,7 +34,3 @@
|
||||
@property (weak, nonatomic) id <ASTableDataSource> dataSource;
|
||||
|
||||
@end
|
||||
|
||||
@interface ASTableNode (ASRangeControllerUpdateRangeProtocol) <ASRangeControllerUpdateRangeProtocol>
|
||||
|
||||
@end
|
||||
|
||||
@@ -64,7 +64,12 @@ typedef ASTraitCollection * _Nonnull (^ASDisplayTraitsForTraitWindowSizeBlock)(C
|
||||
|
||||
@interface ASViewController (ASRangeControllerUpdateRangeProtocol)
|
||||
|
||||
/// Automatically adjust range mode based on view events if the containing node confirms to the ASRangeControllerUpdateRangeProtocol
|
||||
/**
|
||||
* Automatically adjust range mode based on view events. If you set this to YES, the view controller or its node
|
||||
* must conform to the ASRangeControllerUpdateRangeProtocol.
|
||||
*
|
||||
* Default value is NO.
|
||||
*/
|
||||
@property (nonatomic, assign) BOOL automaticallyAdjustRangeModeBasedOnViewEvents;
|
||||
|
||||
@end
|
||||
|
||||
@@ -27,6 +27,9 @@
|
||||
BOOL _automaticallyAdjustRangeModeBasedOnViewEvents;
|
||||
BOOL _parentManagesVisibilityDepth;
|
||||
NSInteger _visibilityDepth;
|
||||
BOOL _selfConformsToRangeModeProtocol;
|
||||
BOOL _nodeConformsToRangeModeProtocol;
|
||||
BOOL _didCheckRangeModeProtocolConformance;
|
||||
}
|
||||
|
||||
- (instancetype)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
|
||||
@@ -167,12 +170,25 @@ ASVisibilityDepthImplementation;
|
||||
- (void)updateCurrentRangeModeWithModeIfPossible:(ASLayoutRangeMode)rangeMode
|
||||
{
|
||||
if (!_automaticallyAdjustRangeModeBasedOnViewEvents) { return; }
|
||||
if (![_node conformsToProtocol:@protocol(ASRangeControllerUpdateRangeProtocol)]) {
|
||||
return;
|
||||
|
||||
if (!_didCheckRangeModeProtocolConformance) {
|
||||
_selfConformsToRangeModeProtocol = [self conformsToProtocol:@protocol(ASRangeControllerUpdateRangeProtocol)];
|
||||
_nodeConformsToRangeModeProtocol = [_node conformsToProtocol:@protocol(ASRangeControllerUpdateRangeProtocol)];
|
||||
_didCheckRangeModeProtocolConformance = YES;
|
||||
if (!_selfConformsToRangeModeProtocol && !_nodeConformsToRangeModeProtocol) {
|
||||
NSLog(@"Warning: automaticallyAdjustRangeModeBasedOnViewEvents set to YES in %@, but range mode updating is not possible because neither view controller nor node %@ conform to ASRangeControllerUpdateRangeProtocol.", self, _node);
|
||||
}
|
||||
}
|
||||
|
||||
if (_selfConformsToRangeModeProtocol) {
|
||||
id<ASRangeControllerUpdateRangeProtocol> rangeUpdater = (id<ASRangeControllerUpdateRangeProtocol>)self;
|
||||
[rangeUpdater updateCurrentRangeWithMode:rangeMode];
|
||||
}
|
||||
|
||||
if (_nodeConformsToRangeModeProtocol) {
|
||||
id<ASRangeControllerUpdateRangeProtocol> rangeUpdater = (id<ASRangeControllerUpdateRangeProtocol>)_node;
|
||||
[rangeUpdater updateCurrentRangeWithMode:rangeMode];
|
||||
}
|
||||
|
||||
id<ASRangeControllerUpdateRangeProtocol> updateRangeNode = (id<ASRangeControllerUpdateRangeProtocol>)_node;
|
||||
[updateRangeNode updateCurrentRangeWithMode:rangeMode];
|
||||
}
|
||||
|
||||
#pragma mark - Layout Helpers
|
||||
|
||||
@@ -599,3 +599,12 @@ static ASLayoutRangeMode __rangeModeForMemoryWarnings = ASLayoutRangeModeVisible
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation ASDisplayNode (RangeModeConfiguring)
|
||||
|
||||
+ (void)setRangeModeForMemoryWarnings:(ASLayoutRangeMode)rangeMode
|
||||
{
|
||||
[ASRangeController setRangeModeForMemoryWarnings:rangeMode];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -18,21 +18,4 @@
|
||||
*/
|
||||
- (void)updateCurrentRangeWithMode:(ASLayoutRangeMode)rangeMode;
|
||||
|
||||
/**
|
||||
* Only ASLayoutRangeModeVisibleOnly or ASLayoutRangeModeLowMemory are recommended. Default is ASLayoutRangeModeVisibleOnly,
|
||||
* because this is the only way to ensure an application will not have blank / flashing views as the user navigates back after
|
||||
* a memory warning. Apps that wish to use the more effective / aggressive ASLayoutRangeModeLowMemory may need to take steps
|
||||
* to mitigate this behavior, including: restoring a larger range mode to the next controller before the user navigates there,
|
||||
* enabling .neverShowPlaceholders on ASCellNodes so that the navigation operation is blocked on redisplay completing, etc.
|
||||
*/
|
||||
+ (void)setRangeModeForMemoryWarnings:(ASLayoutRangeMode)rangeMode;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#import "ASCollectionDataController.h"
|
||||
#import "ASCollectionViewFlowLayoutInspector.h"
|
||||
#import "ASCellNode.h"
|
||||
#import "ASCollectionNode.h"
|
||||
|
||||
@interface ASTextCellNodeWithSetSelectedCounter : ASTextCellNode
|
||||
|
||||
@@ -241,4 +242,14 @@
|
||||
XCTAssertTrue(ASRangeTuningParametersEqualToRangeTuningParameters(preloadParams, [collectionView tuningParametersForRangeType:ASLayoutRangeTypeFetchData]));
|
||||
}
|
||||
|
||||
/**
|
||||
* This may seem silly, but we had issues where the runtime sometimes wouldn't correctly report
|
||||
* conformances declared on categories.
|
||||
*/
|
||||
- (void)testThatCollectionNodeConformsToExpectedProtocols
|
||||
{
|
||||
ASCollectionNode *node = [[ASCollectionNode alloc] initWithFrame:CGRectZero collectionViewLayout:[[UICollectionViewFlowLayout alloc] init]];
|
||||
XCTAssert([node conformsToProtocol:@protocol(ASRangeControllerUpdateRangeProtocol)]);
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#import "ASDisplayNode+Subclasses.h"
|
||||
#import "ASChangeSetDataController.h"
|
||||
#import "ASCellNode.h"
|
||||
#import "ASTableNode.h"
|
||||
|
||||
#define NumberOfSections 10
|
||||
#define NumberOfRowsPerSection 20
|
||||
@@ -518,4 +519,14 @@
|
||||
}];
|
||||
}
|
||||
|
||||
/**
|
||||
* This may seem silly, but we had issues where the runtime sometimes wouldn't correctly report
|
||||
* conformances declared on categories.
|
||||
*/
|
||||
- (void)testThatTableNodeConformsToExpectedProtocols
|
||||
{
|
||||
ASTableNode *node = [[ASTableNode alloc] initWithStyle:UITableViewStylePlain];
|
||||
XCTAssert([node conformsToProtocol:@protocol(ASRangeControllerUpdateRangeProtocol)]);
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
Reference in New Issue
Block a user