mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-08-31 18:02:20 +00:00
Make Cell Node Properties Atomic (#74)
* Make ASCellNode indexPath and supplementaryElementKind atomic * Update the change log * Fix licenses * Be explicit with atomic * Rename the protocol * And the file
This commit is contained in:
parent
471f02daa7
commit
a7656766f9
@ -368,6 +368,7 @@
|
||||
CCA282D01E9EBF6C0037E8B7 /* ASTipsWindow.h in Headers */ = {isa = PBXBuildFile; fileRef = CCA282CE1E9EBF6C0037E8B7 /* ASTipsWindow.h */; };
|
||||
CCA282D11E9EBF6C0037E8B7 /* ASTipsWindow.m in Sources */ = {isa = PBXBuildFile; fileRef = CCA282CF1E9EBF6C0037E8B7 /* ASTipsWindow.m */; };
|
||||
CCB2F34D1D63CCC6004E6DE9 /* ASDisplayNodeSnapshotTests.m in Sources */ = {isa = PBXBuildFile; fileRef = CCB2F34C1D63CCC6004E6DE9 /* ASDisplayNodeSnapshotTests.m */; };
|
||||
CCBBBF5D1EB161760069AA91 /* ASRangeManagingNode.h in Headers */ = {isa = PBXBuildFile; fileRef = CCBBBF5C1EB161760069AA91 /* ASRangeManagingNode.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
CCF18FF41D2575E300DF5895 /* NSIndexSet+ASHelpers.h in Headers */ = {isa = PBXBuildFile; fileRef = CC4981BA1D1C7F65004E13CC /* NSIndexSet+ASHelpers.h */; settings = {ATTRIBUTES = (Private, ); }; };
|
||||
DB55C2671C641AE4004EDCF5 /* ASContextTransitioning.h in Headers */ = {isa = PBXBuildFile; fileRef = DB55C2651C641AE4004EDCF5 /* ASContextTransitioning.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
DB7121BCD50849C498C886FB /* libPods-AsyncDisplayKitTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = EFA731F0396842FF8AB635EE /* libPods-AsyncDisplayKitTests.a */; };
|
||||
@ -798,6 +799,7 @@
|
||||
CCA282CE1E9EBF6C0037E8B7 /* ASTipsWindow.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASTipsWindow.h; sourceTree = "<group>"; };
|
||||
CCA282CF1E9EBF6C0037E8B7 /* ASTipsWindow.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASTipsWindow.m; sourceTree = "<group>"; };
|
||||
CCB2F34C1D63CCC6004E6DE9 /* ASDisplayNodeSnapshotTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASDisplayNodeSnapshotTests.m; sourceTree = "<group>"; };
|
||||
CCBBBF5C1EB161760069AA91 /* ASRangeManagingNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASRangeManagingNode.h; sourceTree = "<group>"; };
|
||||
CCBD05DE1E4147B000D18509 /* ASIGListAdapterBasedDataSource.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASIGListAdapterBasedDataSource.m; sourceTree = "<group>"; };
|
||||
CCBD05DF1E4147B000D18509 /* ASIGListAdapterBasedDataSource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASIGListAdapterBasedDataSource.h; sourceTree = "<group>"; };
|
||||
CCE04B1E1E313EA7006AEBBB /* ASSectionController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASSectionController.h; sourceTree = "<group>"; };
|
||||
@ -1002,6 +1004,7 @@
|
||||
25E327551C16819500A2170C /* ASPagerNode.m */,
|
||||
A2763D771CBDD57D00A9ADBD /* ASPINRemoteImageDownloader.h */,
|
||||
A2763D781CBDD57D00A9ADBD /* ASPINRemoteImageDownloader.m */,
|
||||
CCBBBF5C1EB161760069AA91 /* ASRangeManagingNode.h */,
|
||||
ACE87A2B1D73696800D7FF06 /* ASSectionContext.h */,
|
||||
D785F6601A74327E00291744 /* ASScrollNode.h */,
|
||||
D785F6611A74327E00291744 /* ASScrollNode.mm */,
|
||||
@ -1533,6 +1536,7 @@
|
||||
509E68611B3AEDA0009B9150 /* ASAbstractLayoutController.h in Headers */,
|
||||
CCA282B81E9EA8E40037E8B7 /* AsyncDisplayKit+Tips.h in Headers */,
|
||||
B35062571B010F070018CF92 /* ASAssert.h in Headers */,
|
||||
CCBBBF5D1EB161760069AA91 /* ASRangeManagingNode.h in Headers */,
|
||||
B35062581B010F070018CF92 /* ASAvailability.h in Headers */,
|
||||
DE84918D1C8FFF2B003D89E9 /* ASRunLoopQueue.h in Headers */,
|
||||
CC0F88621E4281E200576FED /* ASSectionController.h in Headers */,
|
||||
|
@ -5,6 +5,7 @@
|
||||
- Fix `__has_include` check in ASLog.h [Philipp Smorygo](Philipp.Smorygo@jetbrains.com)
|
||||
- Fix potential deadlock in ASControlNode [Garrett Moon](https://github.com/garrettmoon)
|
||||
- [Yoga Beta] Improvements to the experimental support for Yoga layout [Scott Goodson](appleguy)
|
||||
- Make cell node `indexPath` and `supplementaryElementKind` atomic so you can read from any thread. (Adlai-Holler)[https://github.com/Adlai-Holler] (#49)[https://github.com/TextureGroup/Texture/pull/74]
|
||||
- Update the rasterization API and un-deprecate it. [Adlai Holler](https://github.com/Adlai-Holler)[#82](https://github.com/TextureGroup/Texture/pull/49)
|
||||
- Simplified & optimized hashing code. [Adlai Holler](https://github.com/Adlai-Holler) [#86](https://github.com/TextureGroup/Texture/pull/86)
|
||||
- Improve the performance & safety of ASDisplayNode subnodes. [Adlai Holler](https://github.com/Adlai-Holler) [#223](https://github.com/TextureGroup/Texture/pull/223)
|
||||
|
@ -20,6 +20,7 @@
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@class ASCellNode, ASTextNode;
|
||||
@protocol ASRangeManagingNode;
|
||||
|
||||
typedef NSUInteger ASCellNodeAnimation;
|
||||
|
||||
@ -87,7 +88,7 @@ typedef NS_ENUM(NSUInteger, ASCellNodeVisibilityEvent) {
|
||||
* @return The supplementary element kind, or @c nil if this node does not represent a supplementary element.
|
||||
*/
|
||||
//TODO change this to be a generic "kind" or "elementKind" that exposes `nil` for row kind
|
||||
@property (nonatomic, copy, readonly, nullable) NSString *supplementaryElementKind;
|
||||
@property (atomic, copy, readonly, nullable) NSString *supplementaryElementKind;
|
||||
|
||||
/*
|
||||
* The layout attributes currently assigned to this node, if any.
|
||||
@ -113,10 +114,8 @@ typedef NS_ENUM(NSUInteger, ASCellNodeVisibilityEvent) {
|
||||
/**
|
||||
* The current index path of this cell node, or @c nil if this node is
|
||||
* not a valid item inside a table node or collection node.
|
||||
*
|
||||
* @note This property must be accessed on the main thread.
|
||||
*/
|
||||
@property (nonatomic, readonly, nullable) NSIndexPath *indexPath;
|
||||
@property (atomic, readonly, nullable) NSIndexPath *indexPath;
|
||||
|
||||
/**
|
||||
* The backing view controller, or @c nil if the node wasn't initialized with backing view controller
|
||||
@ -126,10 +125,9 @@ typedef NS_ENUM(NSUInteger, ASCellNodeVisibilityEvent) {
|
||||
|
||||
|
||||
/**
|
||||
* The owning node (ASCollectionNode/ASTableNode) of this cell node, or @c nil if this node is
|
||||
* not a valid item inside a table node or collection node or if those nodes are nil.
|
||||
* The table- or collection-node that this cell is a member of, if any.
|
||||
*/
|
||||
@property (weak, nonatomic, readonly, nullable) ASDisplayNode *owningNode;
|
||||
@property (atomic, weak, readonly, nullable) id<ASRangeManagingNode> owningNode;
|
||||
|
||||
/*
|
||||
* ASCellNode must forward touch events in order for UITableView and UICollectionView tap handling to work. Overriding
|
||||
|
@ -44,12 +44,6 @@
|
||||
ASDisplayNode *_viewControllerNode;
|
||||
UIViewController *_viewController;
|
||||
BOOL _suspendInteractionDelegate;
|
||||
|
||||
struct {
|
||||
unsigned int isTableNode:1;
|
||||
unsigned int isCollectionNode:1;
|
||||
} _owningNodeType;
|
||||
|
||||
}
|
||||
|
||||
@end
|
||||
@ -165,19 +159,6 @@
|
||||
}
|
||||
}
|
||||
|
||||
- (void)setOwningNode:(ASDisplayNode *)owningNode
|
||||
{
|
||||
_owningNode = owningNode;
|
||||
|
||||
memset(&_owningNodeType, 0, sizeof(_owningNodeType));
|
||||
|
||||
if ([owningNode isKindOfClass:[ASTableNode class]]) {
|
||||
_owningNodeType.isTableNode = 1;
|
||||
} else if ([owningNode isKindOfClass:[ASCollectionNode class]]) {
|
||||
_owningNodeType.isCollectionNode = 1;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)__setSelectedFromUIKit:(BOOL)selected;
|
||||
{
|
||||
if (selected != _selected) {
|
||||
@ -198,15 +179,7 @@
|
||||
|
||||
- (NSIndexPath *)indexPath
|
||||
{
|
||||
ASDisplayNodeAssertMainThread();
|
||||
|
||||
if (_owningNodeType.isTableNode) {
|
||||
return [(ASTableNode *)self.owningNode indexPathForNode:self];
|
||||
} else if (_owningNodeType.isCollectionNode) {
|
||||
return [(ASCollectionNode *)self.owningNode indexPathForNode:self];
|
||||
}
|
||||
|
||||
return nil;
|
||||
return [self.owningNode indexPathForNode:self];
|
||||
}
|
||||
|
||||
- (UIViewController *)viewController
|
||||
|
@ -20,6 +20,7 @@
|
||||
#import <AsyncDisplayKit/ASRangeControllerUpdateRangeProtocol+Beta.h>
|
||||
#import <AsyncDisplayKit/ASCollectionView.h>
|
||||
#import <AsyncDisplayKit/ASBlockTypes.h>
|
||||
#import <AsyncDisplayKit/ASRangeManagingNode.h>
|
||||
|
||||
@protocol ASCollectionViewLayoutFacilitatorProtocol;
|
||||
@protocol ASCollectionDelegate;
|
||||
@ -32,7 +33,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 <ASRangeControllerUpdateRangeProtocol>
|
||||
@interface ASCollectionNode : ASDisplayNode <ASRangeControllerUpdateRangeProtocol, ASRangeManagingNode>
|
||||
|
||||
- (instancetype)init NS_UNAVAILABLE;
|
||||
|
||||
|
@ -155,7 +155,7 @@
|
||||
__weak __typeof__(self) weakSelf = self;
|
||||
[self setViewBlock:^{
|
||||
__typeof__(self) strongSelf = weakSelf;
|
||||
return [[[strongSelf collectionViewClass] alloc] _initWithFrame:frame collectionViewLayout:strongSelf->_pendingState.collectionViewLayout layoutFacilitator:layoutFacilitator eventLog:ASDisplayNodeGetEventLog(strongSelf)];
|
||||
return [[[strongSelf collectionViewClass] alloc] _initWithFrame:frame collectionViewLayout:strongSelf->_pendingState.collectionViewLayout layoutFacilitator:layoutFacilitator owningNode:strongSelf eventLog:ASDisplayNodeGetEventLog(strongSelf)];
|
||||
}];
|
||||
}
|
||||
return self;
|
||||
|
@ -80,7 +80,7 @@ static NSString * const kReuseIdentifier = @"_ASCollectionReuseIdentifier";
|
||||
#pragma mark -
|
||||
#pragma mark ASCollectionView.
|
||||
|
||||
@interface ASCollectionView () <ASRangeControllerDataSource, ASRangeControllerDelegate, ASDataControllerSource, ASCellNodeInteractionDelegate, ASDelegateProxyInterceptor, ASBatchFetchingScrollView, ASDataControllerEnvironmentDelegate, ASCALayerExtendedDelegate, UICollectionViewDelegateFlowLayout> {
|
||||
@interface ASCollectionView () <ASRangeControllerDataSource, ASRangeControllerDelegate, ASDataControllerSource, ASCellNodeInteractionDelegate, ASDelegateProxyInterceptor, ASBatchFetchingScrollView, ASCALayerExtendedDelegate, UICollectionViewDelegateFlowLayout> {
|
||||
ASCollectionViewProxy *_proxyDataSource;
|
||||
ASCollectionViewProxy *_proxyDelegate;
|
||||
|
||||
@ -250,10 +250,10 @@ static NSString * const kReuseIdentifier = @"_ASCollectionReuseIdentifier";
|
||||
|
||||
- (instancetype)initWithFrame:(CGRect)frame collectionViewLayout:(UICollectionViewLayout *)layout
|
||||
{
|
||||
return [self _initWithFrame:frame collectionViewLayout:layout layoutFacilitator:nil eventLog:nil];
|
||||
return [self _initWithFrame:frame collectionViewLayout:layout layoutFacilitator:nil owningNode:nil eventLog:nil];
|
||||
}
|
||||
|
||||
- (instancetype)_initWithFrame:(CGRect)frame collectionViewLayout:(UICollectionViewLayout *)layout layoutFacilitator:(id<ASCollectionViewLayoutFacilitatorProtocol>)layoutFacilitator eventLog:(ASEventLog *)eventLog
|
||||
- (instancetype)_initWithFrame:(CGRect)frame collectionViewLayout:(UICollectionViewLayout *)layout layoutFacilitator:(id<ASCollectionViewLayoutFacilitatorProtocol>)layoutFacilitator owningNode:(ASCollectionNode *)owningNode eventLog:(ASEventLog *)eventLog
|
||||
{
|
||||
if (!(self = [super initWithFrame:frame collectionViewLayout:layout]))
|
||||
return nil;
|
||||
@ -273,9 +273,8 @@ static NSString * const kReuseIdentifier = @"_ASCollectionReuseIdentifier";
|
||||
_rangeController.delegate = self;
|
||||
_rangeController.layoutController = _layoutController;
|
||||
|
||||
_dataController = [[ASDataController alloc] initWithDataSource:self eventLog:eventLog];
|
||||
_dataController = [[ASDataController alloc] initWithDataSource:self node:owningNode eventLog:eventLog];
|
||||
_dataController.delegate = _rangeController;
|
||||
_dataController.environmentDelegate = self;
|
||||
|
||||
_batchContext = [[ASBatchContext alloc] init];
|
||||
|
||||
@ -1649,11 +1648,6 @@ static NSString * const kReuseIdentifier = @"_ASCollectionReuseIdentifier";
|
||||
|
||||
}
|
||||
|
||||
- (id<ASTraitEnvironment>)dataControllerEnvironment
|
||||
{
|
||||
return self.collectionNode;
|
||||
}
|
||||
|
||||
#pragma mark - ASDataControllerSource optional methods
|
||||
|
||||
- (ASCellNodeBlock)dataController:(ASDataController *)dataController supplementaryNodeBlockOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath
|
||||
|
35
Source/ASRangeManagingNode.h
Normal file
35
Source/ASRangeManagingNode.h
Normal file
@ -0,0 +1,35 @@
|
||||
//
|
||||
// ASRangeManagingNode.h
|
||||
// Texture
|
||||
//
|
||||
// Copyright (c) 2017-present, Pinterest, Inc. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <AsyncDisplayKit/ASTraitCollection.h>
|
||||
|
||||
@class ASCellNode;
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
/**
|
||||
* Basically ASTableNode or ASCollectionNode.
|
||||
*/
|
||||
@protocol ASRangeManagingNode <NSObject, ASTraitEnvironment>
|
||||
|
||||
/**
|
||||
* Retrieve the index path for the given node, if it's a member of this container.
|
||||
*
|
||||
* @param node The node.
|
||||
* @return The index path, or nil if the node is not part of this container.
|
||||
*/
|
||||
- (nullable NSIndexPath *)indexPathForNode:(ASCellNode *)node;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
@ -19,7 +19,7 @@
|
||||
#import <AsyncDisplayKit/ASDisplayNode.h>
|
||||
#import <AsyncDisplayKit/ASRangeControllerUpdateRangeProtocol+Beta.h>
|
||||
#import <AsyncDisplayKit/ASTableView.h>
|
||||
|
||||
#import <AsyncDisplayKit/ASRangeManagingNode.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@ -31,7 +31,7 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
* 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 <ASRangeControllerUpdateRangeProtocol>
|
||||
@interface ASTableNode : ASDisplayNode <ASRangeControllerUpdateRangeProtocol, ASRangeManagingNode>
|
||||
|
||||
- (instancetype)init; // UITableViewStylePlain
|
||||
- (instancetype)initWithStyle:(UITableViewStyle)style NS_DESIGNATED_INITIALIZER;
|
||||
|
@ -80,7 +80,7 @@
|
||||
[self setViewBlock:^{
|
||||
// Variable will be unused if event logging is off.
|
||||
__unused __typeof__(self) strongSelf = weakSelf;
|
||||
return [[ASTableView alloc] _initWithFrame:CGRectZero style:style dataControllerClass:nil eventLog:ASDisplayNodeGetEventLog(strongSelf)];
|
||||
return [[ASTableView alloc] _initWithFrame:CGRectZero style:style dataControllerClass:nil owningNode:strongSelf eventLog:ASDisplayNodeGetEventLog(strongSelf)];
|
||||
}];
|
||||
}
|
||||
return self;
|
||||
|
@ -147,7 +147,7 @@ static NSString * const kCellReuseIdentifier = @"_ASTableViewCell";
|
||||
#pragma mark -
|
||||
#pragma mark ASTableView
|
||||
|
||||
@interface ASTableView () <ASRangeControllerDataSource, ASRangeControllerDelegate, ASDataControllerSource, _ASTableViewCellDelegate, ASCellNodeInteractionDelegate, ASDelegateProxyInterceptor, ASBatchFetchingScrollView, ASDataControllerEnvironmentDelegate>
|
||||
@interface ASTableView () <ASRangeControllerDataSource, ASRangeControllerDelegate, ASDataControllerSource, _ASTableViewCellDelegate, ASCellNodeInteractionDelegate, ASDelegateProxyInterceptor, ASBatchFetchingScrollView>
|
||||
{
|
||||
ASTableViewProxy *_proxyDataSource;
|
||||
ASTableViewProxy *_proxyDelegate;
|
||||
@ -286,8 +286,22 @@ static NSString * const kCellReuseIdentifier = @"_ASTableViewCell";
|
||||
#pragma mark -
|
||||
#pragma mark Lifecycle
|
||||
|
||||
- (void)configureWithDataControllerClass:(Class)dataControllerClass eventLog:(ASEventLog *)eventLog
|
||||
- (instancetype)initWithFrame:(CGRect)frame style:(UITableViewStyle)style
|
||||
{
|
||||
return [self _initWithFrame:frame style:style dataControllerClass:nil owningNode:nil eventLog:nil];
|
||||
}
|
||||
|
||||
- (instancetype)_initWithFrame:(CGRect)frame style:(UITableViewStyle)style dataControllerClass:(Class)dataControllerClass owningNode:(ASTableNode *)tableNode eventLog:(ASEventLog *)eventLog
|
||||
{
|
||||
if (!(self = [super initWithFrame:frame style:style])) {
|
||||
return nil;
|
||||
}
|
||||
_cellsForVisibilityUpdates = [NSMutableSet set];
|
||||
_cellsForLayoutUpdates = [NSMutableSet set];
|
||||
if (!dataControllerClass) {
|
||||
dataControllerClass = [[self class] dataControllerClass];
|
||||
}
|
||||
|
||||
_layoutController = [[ASTableLayoutController alloc] initWithTableView:self];
|
||||
|
||||
_rangeController = [[ASRangeController alloc] init];
|
||||
@ -295,13 +309,12 @@ static NSString * const kCellReuseIdentifier = @"_ASTableViewCell";
|
||||
_rangeController.dataSource = self;
|
||||
_rangeController.delegate = self;
|
||||
|
||||
_dataController = [[dataControllerClass alloc] initWithDataSource:self eventLog:eventLog];
|
||||
_dataController = [[dataControllerClass alloc] initWithDataSource:self node:tableNode eventLog:eventLog];
|
||||
_dataController.delegate = _rangeController;
|
||||
_dataController.environmentDelegate = self;
|
||||
|
||||
|
||||
_leadingScreensForBatching = 2.0;
|
||||
_batchContext = [[ASBatchContext alloc] init];
|
||||
|
||||
|
||||
_automaticallyAdjustsContentOffset = NO;
|
||||
|
||||
_nodesConstrainedWidth = self.bounds.size.width;
|
||||
@ -313,25 +326,6 @@ static NSString * const kCellReuseIdentifier = @"_ASTableViewCell";
|
||||
super.dataSource = (id<UITableViewDataSource>)_proxyDataSource;
|
||||
|
||||
[self registerClass:_ASTableViewCell.class forCellReuseIdentifier:kCellReuseIdentifier];
|
||||
}
|
||||
|
||||
- (instancetype)initWithFrame:(CGRect)frame style:(UITableViewStyle)style
|
||||
{
|
||||
return [self _initWithFrame:frame style:style dataControllerClass:nil eventLog:nil];
|
||||
}
|
||||
|
||||
- (instancetype)_initWithFrame:(CGRect)frame style:(UITableViewStyle)style dataControllerClass:(Class)dataControllerClass eventLog:(ASEventLog *)eventLog
|
||||
{
|
||||
if (!(self = [super initWithFrame:frame style:style])) {
|
||||
return nil;
|
||||
}
|
||||
_cellsForVisibilityUpdates = [NSMutableSet set];
|
||||
_cellsForLayoutUpdates = [NSMutableSet set];
|
||||
if (!dataControllerClass) {
|
||||
dataControllerClass = [[self class] dataControllerClass];
|
||||
}
|
||||
|
||||
[self configureWithDataControllerClass:dataControllerClass eventLog:eventLog];
|
||||
|
||||
if (!AS_AT_LEAST_IOS9) {
|
||||
_retainedLayer = self.layer;
|
||||
@ -1734,13 +1728,6 @@ static NSString * const kCellReuseIdentifier = @"_ASTableViewCell";
|
||||
return (fabs(rect.size.height - size.height) < FLT_EPSILON);
|
||||
}
|
||||
|
||||
#pragma mark - ASDataControllerEnvironmentDelegate
|
||||
|
||||
- (id<ASTraitEnvironment>)dataControllerEnvironment
|
||||
{
|
||||
return self.tableNode;
|
||||
}
|
||||
|
||||
#pragma mark - _ASTableViewCellDelegate
|
||||
|
||||
- (void)didLayoutSubviewsOfTableViewCell:(_ASTableViewCell *)tableViewCell
|
||||
|
@ -40,7 +40,7 @@
|
||||
*
|
||||
* @param eventLog An event log passed through to the data controller.
|
||||
*/
|
||||
- (instancetype)_initWithFrame:(CGRect)frame style:(UITableViewStyle)style dataControllerClass:(Class)dataControllerClass eventLog:(ASEventLog *)eventLog;
|
||||
- (instancetype)_initWithFrame:(CGRect)frame style:(UITableViewStyle)style dataControllerClass:(Class)dataControllerClass owningNode:(ASTableNode *)tableNode eventLog:(ASEventLog *)eventLog;
|
||||
|
||||
/// Set YES and we'll log every time we call [super insertRows…] etc
|
||||
@property (nonatomic) BOOL test_enableSuperUpdateCallLogging;
|
||||
|
@ -43,6 +43,7 @@
|
||||
#import <AsyncDisplayKit/ASCollectionViewLayoutInspector.h>
|
||||
#import <AsyncDisplayKit/ASCollectionViewLayoutFacilitatorProtocol.h>
|
||||
#import <AsyncDisplayKit/ASCellNode.h>
|
||||
#import <AsyncDisplayKit/ASRangeManagingNode.h>
|
||||
#import <AsyncDisplayKit/ASSectionContext.h>
|
||||
|
||||
#import <AsyncDisplayKit/ASElementMap.h>
|
||||
|
@ -19,6 +19,7 @@
|
||||
#import <AsyncDisplayKit/ASTraitCollection.h>
|
||||
|
||||
@class ASDisplayNode;
|
||||
@protocol ASRangeManagingNode;
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@ -28,13 +29,13 @@ AS_SUBCLASSING_RESTRICTED
|
||||
//TODO change this to be a generic "kind" or "elementKind" that exposes `nil` for row kind
|
||||
@property (nonatomic, readonly, copy, nullable) NSString *supplementaryElementKind;
|
||||
@property (nonatomic, assign) ASSizeRange constrainedSize;
|
||||
@property (nonatomic, weak) ASDisplayNode *owningNode;
|
||||
@property (nonatomic, readonly, weak) id<ASRangeManagingNode> owningNode;
|
||||
@property (nonatomic, assign) ASPrimitiveTraitCollection traitCollection;
|
||||
|
||||
- (instancetype)initWithNodeBlock:(ASCellNodeBlock)nodeBlock
|
||||
supplementaryElementKind:(nullable NSString *)supplementaryElementKind
|
||||
constrainedSize:(ASSizeRange)constrainedSize
|
||||
owningNode:(ASDisplayNode *)owningNode
|
||||
owningNode:(id<ASRangeManagingNode>)owningNode
|
||||
traitCollection:(ASPrimitiveTraitCollection)traitCollection;
|
||||
|
||||
/**
|
||||
|
@ -34,7 +34,7 @@
|
||||
- (instancetype)initWithNodeBlock:(ASCellNodeBlock)nodeBlock
|
||||
supplementaryElementKind:(NSString *)supplementaryElementKind
|
||||
constrainedSize:(ASSizeRange)constrainedSize
|
||||
owningNode:(ASDisplayNode *)owningNode
|
||||
owningNode:(id<ASRangeManagingNode>)owningNode
|
||||
traitCollection:(ASPrimitiveTraitCollection)traitCollection
|
||||
{
|
||||
NSAssert(nodeBlock != nil, @"Node block must not be nil");
|
||||
|
@ -25,7 +25,7 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
@class ASRangeController;
|
||||
|
||||
@interface ASCollectionView ()
|
||||
- (instancetype)_initWithFrame:(CGRect)frame collectionViewLayout:(UICollectionViewLayout *)layout layoutFacilitator:(nullable id<ASCollectionViewLayoutFacilitatorProtocol>)layoutFacilitator eventLog:(nullable ASEventLog *)eventLog;
|
||||
- (instancetype)_initWithFrame:(CGRect)frame collectionViewLayout:(UICollectionViewLayout *)layout layoutFacilitator:(nullable id<ASCollectionViewLayoutFacilitatorProtocol>)layoutFacilitator owningNode:(nullable ASCollectionNode *)owningNode eventLog:(nullable ASEventLog *)eventLog;
|
||||
|
||||
@property (nonatomic, weak, readwrite) ASCollectionNode *collectionNode;
|
||||
@property (nonatomic, strong, readonly) ASDataController *dataController;
|
||||
|
@ -39,6 +39,7 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
@class ASElementMap;
|
||||
@class ASLayout;
|
||||
@class _ASHierarchyChangeSet;
|
||||
@protocol ASRangeManagingNode;
|
||||
@protocol ASTraitEnvironment;
|
||||
@protocol ASSectionContext;
|
||||
|
||||
@ -96,12 +97,6 @@ extern NSString * const ASCollectionInvalidUpdateException;
|
||||
|
||||
@end
|
||||
|
||||
@protocol ASDataControllerEnvironmentDelegate
|
||||
|
||||
- (nullable id<ASTraitEnvironment>)dataControllerEnvironment;
|
||||
|
||||
@end
|
||||
|
||||
/**
|
||||
Delegate for notify the data updating of data controller.
|
||||
These methods will be invoked from main thread right now, but it may be moved to background thread in the future.
|
||||
@ -160,17 +155,30 @@ extern NSString * const ASCollectionInvalidUpdateException;
|
||||
*/
|
||||
@interface ASDataController : NSObject
|
||||
|
||||
- (instancetype)initWithDataSource:(id<ASDataControllerSource>)dataSource eventLog:(nullable ASEventLog *)eventLog NS_DESIGNATED_INITIALIZER;
|
||||
- (instancetype)initWithDataSource:(id<ASDataControllerSource>)dataSource node:(nullable id<ASRangeManagingNode>)node eventLog:(nullable ASEventLog *)eventLog NS_DESIGNATED_INITIALIZER;
|
||||
|
||||
- (instancetype)init NS_UNAVAILABLE;
|
||||
|
||||
/**
|
||||
* The node that owns this data controller, if any.
|
||||
*
|
||||
* NOTE: Soon we will drop support for using ASTableView/ASCollectionView without the node, so this will be non-null.
|
||||
*/
|
||||
@property (nonatomic, nullable, weak, readonly) id<ASRangeManagingNode> node;
|
||||
|
||||
/**
|
||||
* The map that is currently displayed. The "UIKit index space."
|
||||
*
|
||||
* This property will only be changed on the main thread.
|
||||
*/
|
||||
@property (nonatomic, strong, readonly) ASElementMap *visibleMap;
|
||||
@property (atomic, copy, readonly) ASElementMap *visibleMap;
|
||||
|
||||
/**
|
||||
* The latest map fetched from the data source. May be more recent than @c visibleMap.
|
||||
*
|
||||
* This property will only be changed on the main thread.
|
||||
*/
|
||||
@property (nonatomic, strong, readonly) ASElementMap *pendingMap;
|
||||
@property (atomic, copy, readonly) ASElementMap *pendingMap;
|
||||
|
||||
/**
|
||||
Data source for fetching data info.
|
||||
@ -187,11 +195,6 @@ extern NSString * const ASCollectionInvalidUpdateException;
|
||||
*/
|
||||
@property (nonatomic, weak) id<ASDataControllerDelegate> delegate;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
@property (nonatomic, weak) id<ASDataControllerEnvironmentDelegate> environmentDelegate;
|
||||
|
||||
/**
|
||||
* Delegate for preparing layouts. Main thead only.
|
||||
*/
|
||||
|
@ -27,6 +27,7 @@
|
||||
#import <AsyncDisplayKit/ASLayout.h>
|
||||
#import <AsyncDisplayKit/ASMainSerialQueue.h>
|
||||
#import <AsyncDisplayKit/ASMutableElementMap.h>
|
||||
#import <AsyncDisplayKit/ASRangeManagingNode.h>
|
||||
#import <AsyncDisplayKit/ASThread.h>
|
||||
#import <AsyncDisplayKit/ASTwoDimensionalArrayUtils.h>
|
||||
#import <AsyncDisplayKit/ASSection.h>
|
||||
@ -85,18 +86,21 @@ typedef void (^ASDataControllerCompletionBlock)(NSArray<ASCollectionElement *> *
|
||||
} _dataSourceFlags;
|
||||
}
|
||||
|
||||
@property (atomic, copy, readwrite) ASElementMap *pendingMap;
|
||||
@property (atomic, copy, readwrite) ASElementMap *visibleMap;
|
||||
@end
|
||||
|
||||
@implementation ASDataController
|
||||
|
||||
#pragma mark - Lifecycle
|
||||
|
||||
- (instancetype)initWithDataSource:(id<ASDataControllerSource>)dataSource eventLog:(ASEventLog *)eventLog
|
||||
- (instancetype)initWithDataSource:(id<ASDataControllerSource>)dataSource node:(nullable id<ASRangeManagingNode>)node eventLog:(ASEventLog *)eventLog
|
||||
{
|
||||
if (!(self = [super init])) {
|
||||
return nil;
|
||||
}
|
||||
|
||||
_node = node;
|
||||
_dataSource = dataSource;
|
||||
|
||||
_dataSourceFlags.supplementaryNodeKindsInSections = [_dataSource respondsToSelector:@selector(dataController:supplementaryNodeKindsInSections:)];
|
||||
@ -110,7 +114,7 @@ typedef void (^ASDataControllerCompletionBlock)(NSArray<ASCollectionElement *> *
|
||||
_eventLog = eventLog;
|
||||
#endif
|
||||
|
||||
_visibleMap = _pendingMap = [[ASElementMap alloc] init];
|
||||
self.visibleMap = self.pendingMap = [[ASElementMap alloc] init];
|
||||
|
||||
_nextSectionID = 0;
|
||||
|
||||
@ -124,14 +128,6 @@ typedef void (^ASDataControllerCompletionBlock)(NSArray<ASCollectionElement *> *
|
||||
return self;
|
||||
}
|
||||
|
||||
- (instancetype)init
|
||||
{
|
||||
ASDisplayNodeFailAssert(@"Failed to call designated initializer.");
|
||||
id<ASDataControllerSource> fakeDataSource = nil;
|
||||
ASEventLog *eventLog = nil;
|
||||
return [self initWithDataSource:fakeDataSource eventLog:eventLog];
|
||||
}
|
||||
|
||||
+ (NSUInteger)parallelProcessorCount
|
||||
{
|
||||
static NSUInteger parallelProcessorCount;
|
||||
@ -277,9 +273,10 @@ typedef void (^ASDataControllerCompletionBlock)(NSArray<ASCollectionElement *> *
|
||||
}
|
||||
}];
|
||||
} else if (_dataSourceFlags.supplementaryNodesOfKindInSection) {
|
||||
id<ASDataControllerSource> dataSource = _dataSource;
|
||||
[sections enumerateRangesUsingBlock:^(NSRange range, BOOL * _Nonnull stop) {
|
||||
for (NSUInteger sectionIndex = range.location; sectionIndex < NSMaxRange(range); sectionIndex++) {
|
||||
NSUInteger itemCount = [_dataSource dataController:self supplementaryNodesOfKind:kind inSection:sectionIndex];
|
||||
NSUInteger itemCount = [dataSource dataController:self supplementaryNodesOfKind:kind inSection:sectionIndex];
|
||||
for (NSUInteger i = 0; i < itemCount; i++) {
|
||||
[indexPaths addObject:[NSIndexPath indexPathForItem:i inSection:sectionIndex]];
|
||||
}
|
||||
@ -296,7 +293,6 @@ typedef void (^ASDataControllerCompletionBlock)(NSArray<ASCollectionElement *> *
|
||||
* @param map The element map into which to apply the change.
|
||||
* @param indexPaths The index paths belongs to sections whose supplementary nodes need to be repopulated.
|
||||
* @param changeSet The changeset that triggered this repopulation.
|
||||
* @param owningNode The node that owns the new elements.
|
||||
* @param traitCollection The trait collection needed to initialize elements
|
||||
* @param indexPathsAreNew YES if index paths are "after the update," NO otherwise.
|
||||
* @param shouldFetchSizeRanges Whether constrained sizes should be fetched from data source
|
||||
@ -304,7 +300,6 @@ typedef void (^ASDataControllerCompletionBlock)(NSArray<ASCollectionElement *> *
|
||||
- (void)_repopulateSupplementaryNodesIntoMap:(ASMutableElementMap *)map
|
||||
forSectionsContainingIndexPaths:(NSArray<NSIndexPath *> *)indexPaths
|
||||
changeSet:(_ASHierarchyChangeSet *)changeSet
|
||||
owningNode:(ASDisplayNode *)owningNode
|
||||
traitCollection:(ASPrimitiveTraitCollection)traitCollection
|
||||
indexPathsAreNew:(BOOL)indexPathsAreNew
|
||||
shouldFetchSizeRanges:(BOOL)shouldFetchSizeRanges
|
||||
@ -330,7 +325,7 @@ typedef void (^ASDataControllerCompletionBlock)(NSArray<ASCollectionElement *> *
|
||||
}
|
||||
|
||||
for (NSString *kind in [self supplementaryKindsInSections:newSections]) {
|
||||
[self _insertElementsIntoMap:map kind:kind forSections:newSections owningNode:owningNode traitCollection:traitCollection shouldFetchSizeRanges:shouldFetchSizeRanges];
|
||||
[self _insertElementsIntoMap:map kind:kind forSections:newSections traitCollection:traitCollection shouldFetchSizeRanges:shouldFetchSizeRanges];
|
||||
}
|
||||
}
|
||||
|
||||
@ -346,7 +341,6 @@ typedef void (^ASDataControllerCompletionBlock)(NSArray<ASCollectionElement *> *
|
||||
- (void)_insertElementsIntoMap:(ASMutableElementMap *)map
|
||||
kind:(NSString *)kind
|
||||
forSections:(NSIndexSet *)sections
|
||||
owningNode:(ASDisplayNode *)owningNode
|
||||
traitCollection:(ASPrimitiveTraitCollection)traitCollection
|
||||
shouldFetchSizeRanges:(BOOL)shouldFetchSizeRanges
|
||||
{
|
||||
@ -357,7 +351,7 @@ typedef void (^ASDataControllerCompletionBlock)(NSArray<ASCollectionElement *> *
|
||||
}
|
||||
|
||||
NSArray<NSIndexPath *> *indexPaths = [self _allIndexPathsForItemsOfKind:kind inSections:sections];
|
||||
[self _insertElementsIntoMap:map kind:kind atIndexPaths:indexPaths owningNode:owningNode traitCollection:traitCollection shouldFetchSizeRanges:shouldFetchSizeRanges];
|
||||
[self _insertElementsIntoMap:map kind:kind atIndexPaths:indexPaths traitCollection:traitCollection shouldFetchSizeRanges:shouldFetchSizeRanges];
|
||||
}
|
||||
|
||||
/**
|
||||
@ -373,7 +367,6 @@ typedef void (^ASDataControllerCompletionBlock)(NSArray<ASCollectionElement *> *
|
||||
- (void)_insertElementsIntoMap:(ASMutableElementMap *)map
|
||||
kind:(NSString *)kind
|
||||
atIndexPaths:(NSArray<NSIndexPath *> *)indexPaths
|
||||
owningNode:(ASDisplayNode *)owningNode
|
||||
traitCollection:(ASPrimitiveTraitCollection)traitCollection
|
||||
shouldFetchSizeRanges:(BOOL)shouldFetchSizeRanges
|
||||
{
|
||||
@ -390,12 +383,14 @@ typedef void (^ASDataControllerCompletionBlock)(NSArray<ASCollectionElement *> *
|
||||
}
|
||||
|
||||
LOG(@"Populating elements of kind: %@, for index paths: %@", kind, indexPaths);
|
||||
id<ASDataControllerSource> dataSource = self.dataSource;
|
||||
id<ASRangeManagingNode> node = self.node;
|
||||
for (NSIndexPath *indexPath in indexPaths) {
|
||||
ASCellNodeBlock nodeBlock;
|
||||
if (isRowKind) {
|
||||
nodeBlock = [_dataSource dataController:self nodeBlockAtIndexPath:indexPath];
|
||||
nodeBlock = [dataSource dataController:self nodeBlockAtIndexPath:indexPath];
|
||||
} else {
|
||||
nodeBlock = [_dataSource dataController:self supplementaryNodeBlockOfKind:kind atIndexPath:indexPath];
|
||||
nodeBlock = [dataSource dataController:self supplementaryNodeBlockOfKind:kind atIndexPath:indexPath];
|
||||
}
|
||||
|
||||
ASSizeRange constrainedSize;
|
||||
@ -406,7 +401,7 @@ typedef void (^ASDataControllerCompletionBlock)(NSArray<ASCollectionElement *> *
|
||||
ASCollectionElement *element = [[ASCollectionElement alloc] initWithNodeBlock:nodeBlock
|
||||
supplementaryElementKind:isRowKind ? nil : kind
|
||||
constrainedSize:constrainedSize
|
||||
owningNode:owningNode
|
||||
owningNode:node
|
||||
traitCollection:traitCollection];
|
||||
[map insertElement:element atIndexPath:indexPath];
|
||||
}
|
||||
@ -544,14 +539,12 @@ typedef void (^ASDataControllerCompletionBlock)(NSArray<ASCollectionElement *> *
|
||||
|
||||
// Step 1: Update the mutable copies to match the data source's state
|
||||
[self _updateSectionContextsInMap:mutableMap changeSet:changeSet];
|
||||
__weak id<ASTraitEnvironment> environment = [self.environmentDelegate dataControllerEnvironment];
|
||||
__weak ASDisplayNode *owningNode = (ASDisplayNode *)environment; // This is gross!
|
||||
ASPrimitiveTraitCollection existingTraitCollection = [environment primitiveTraitCollection];
|
||||
[self _updateElementsInMap:mutableMap changeSet:changeSet owningNode:owningNode traitCollection:existingTraitCollection shouldFetchSizeRanges:(! canDelegateLayout)];
|
||||
ASPrimitiveTraitCollection existingTraitCollection = [self.node primitiveTraitCollection];
|
||||
[self _updateElementsInMap:mutableMap changeSet:changeSet traitCollection:existingTraitCollection shouldFetchSizeRanges:(! canDelegateLayout)];
|
||||
|
||||
// Step 2: Clone the new data
|
||||
ASElementMap *newMap = [mutableMap copy];
|
||||
_pendingMap = newMap;
|
||||
self.pendingMap = newMap;
|
||||
|
||||
// Step 3: Ask layout delegate for contexts
|
||||
id layoutContext = nil;
|
||||
@ -585,7 +578,7 @@ typedef void (^ASDataControllerCompletionBlock)(NSArray<ASCollectionElement *> *
|
||||
[_delegate dataController:self willUpdateWithChangeSet:changeSet];
|
||||
|
||||
// Step 5: Deploy the new data as "completed" and inform delegate
|
||||
_visibleMap = newMap;
|
||||
self.visibleMap = newMap;
|
||||
|
||||
[_delegate dataController:self didUpdateWithChangeSet:changeSet];
|
||||
}];
|
||||
@ -644,7 +637,6 @@ typedef void (^ASDataControllerCompletionBlock)(NSArray<ASCollectionElement *> *
|
||||
*/
|
||||
- (void)_updateElementsInMap:(ASMutableElementMap *)map
|
||||
changeSet:(_ASHierarchyChangeSet *)changeSet
|
||||
owningNode:(ASDisplayNode *)owningNode
|
||||
traitCollection:(ASPrimitiveTraitCollection)traitCollection
|
||||
shouldFetchSizeRanges:(BOOL)shouldFetchSizeRanges
|
||||
{
|
||||
@ -656,7 +648,7 @@ typedef void (^ASDataControllerCompletionBlock)(NSArray<ASCollectionElement *> *
|
||||
NSUInteger sectionCount = [self itemCountsFromDataSource].size();
|
||||
if (sectionCount > 0) {
|
||||
NSIndexSet *sectionIndexes = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, sectionCount)];
|
||||
[self _insertElementsIntoMap:map sections:sectionIndexes owningNode:owningNode traitCollection:traitCollection shouldFetchSizeRanges:shouldFetchSizeRanges];
|
||||
[self _insertElementsIntoMap:map sections:sectionIndexes traitCollection:traitCollection shouldFetchSizeRanges:shouldFetchSizeRanges];
|
||||
}
|
||||
// Return immediately because reloadData can't be used in conjuntion with other updates.
|
||||
return;
|
||||
@ -667,7 +659,6 @@ typedef void (^ASDataControllerCompletionBlock)(NSArray<ASCollectionElement *> *
|
||||
// Aggressively repopulate supplementary nodes (#1773 & #1629)
|
||||
[self _repopulateSupplementaryNodesIntoMap:map forSectionsContainingIndexPaths:change.indexPaths
|
||||
changeSet:changeSet
|
||||
owningNode:owningNode
|
||||
traitCollection:traitCollection
|
||||
indexPathsAreNew:NO
|
||||
shouldFetchSizeRanges:shouldFetchSizeRanges];
|
||||
@ -680,15 +671,14 @@ typedef void (^ASDataControllerCompletionBlock)(NSArray<ASCollectionElement *> *
|
||||
}
|
||||
|
||||
for (_ASHierarchySectionChange *change in [changeSet sectionChangesOfType:_ASHierarchyChangeTypeInsert]) {
|
||||
[self _insertElementsIntoMap:map sections:change.indexSet owningNode:owningNode traitCollection:traitCollection shouldFetchSizeRanges:shouldFetchSizeRanges];
|
||||
[self _insertElementsIntoMap:map sections:change.indexSet traitCollection:traitCollection shouldFetchSizeRanges:shouldFetchSizeRanges];
|
||||
}
|
||||
|
||||
for (_ASHierarchyItemChange *change in [changeSet itemChangesOfType:_ASHierarchyChangeTypeInsert]) {
|
||||
[self _insertElementsIntoMap:map kind:ASDataControllerRowNodeKind atIndexPaths:change.indexPaths owningNode:owningNode traitCollection:traitCollection shouldFetchSizeRanges:shouldFetchSizeRanges];
|
||||
[self _insertElementsIntoMap:map kind:ASDataControllerRowNodeKind atIndexPaths:change.indexPaths traitCollection:traitCollection shouldFetchSizeRanges:shouldFetchSizeRanges];
|
||||
// Aggressively reload supplementary nodes (#1773 & #1629)
|
||||
[self _repopulateSupplementaryNodesIntoMap:map forSectionsContainingIndexPaths:change.indexPaths
|
||||
changeSet:changeSet
|
||||
owningNode:owningNode
|
||||
traitCollection:traitCollection
|
||||
indexPathsAreNew:YES
|
||||
shouldFetchSizeRanges:shouldFetchSizeRanges];
|
||||
@ -697,7 +687,6 @@ typedef void (^ASDataControllerCompletionBlock)(NSArray<ASCollectionElement *> *
|
||||
|
||||
- (void)_insertElementsIntoMap:(ASMutableElementMap *)map
|
||||
sections:(NSIndexSet *)sectionIndexes
|
||||
owningNode:(ASDisplayNode *)owningNode
|
||||
traitCollection:(ASPrimitiveTraitCollection)traitCollection
|
||||
shouldFetchSizeRanges:(BOOL)shouldFetchSizeRanges
|
||||
{
|
||||
@ -709,12 +698,12 @@ typedef void (^ASDataControllerCompletionBlock)(NSArray<ASCollectionElement *> *
|
||||
|
||||
// Items
|
||||
[map insertEmptySectionsOfItemsAtIndexes:sectionIndexes];
|
||||
[self _insertElementsIntoMap:map kind:ASDataControllerRowNodeKind forSections:sectionIndexes owningNode:owningNode traitCollection:traitCollection shouldFetchSizeRanges:shouldFetchSizeRanges];
|
||||
[self _insertElementsIntoMap:map kind:ASDataControllerRowNodeKind forSections:sectionIndexes traitCollection:traitCollection shouldFetchSizeRanges:shouldFetchSizeRanges];
|
||||
|
||||
// Supplementaries
|
||||
for (NSString *kind in [self supplementaryKindsInSections:sectionIndexes]) {
|
||||
// Step 2: Populate new elements for all sections
|
||||
[self _insertElementsIntoMap:map kind:kind forSections:sectionIndexes owningNode:owningNode traitCollection:traitCollection shouldFetchSizeRanges:shouldFetchSizeRanges];
|
||||
[self _insertElementsIntoMap:map kind:kind forSections:sectionIndexes traitCollection:traitCollection shouldFetchSizeRanges:shouldFetchSizeRanges];
|
||||
}
|
||||
}
|
||||
|
||||
@ -729,10 +718,11 @@ typedef void (^ASDataControllerCompletionBlock)(NSArray<ASCollectionElement *> *
|
||||
return;
|
||||
}
|
||||
|
||||
id<ASDataControllerSource> dataSource = self.dataSource;
|
||||
for (ASCellNode *node in nodes) {
|
||||
ASSizeRange constrainedSize = [self constrainedSizeForElement:node.collectionElement inElementMap:_pendingMap];
|
||||
[self _layoutNode:node withConstrainedSize:constrainedSize];
|
||||
BOOL matchesSize = [_dataSource dataController:self presentedSizeForElement:node.collectionElement matchesSize:node.frame.size];
|
||||
BOOL matchesSize = [dataSource dataController:self presentedSizeForElement:node.collectionElement matchesSize:node.frame.size];
|
||||
if (! matchesSize) {
|
||||
[nodesSizesChanged addObject:node];
|
||||
}
|
||||
@ -783,8 +773,9 @@ typedef void (^ASDataControllerCompletionBlock)(NSArray<ASCollectionElement *> *
|
||||
|
||||
// Can't update the trait collection right away because _visibleMap may not be up-to-date,
|
||||
// i.e there might be some elements that were allocated using the old trait collection but haven't been added to _visibleMap
|
||||
|
||||
[self _scheduleBlockOnMainSerialQueue:^{
|
||||
ASPrimitiveTraitCollection newTraitCollection = [[_environmentDelegate dataControllerEnvironment] primitiveTraitCollection];
|
||||
ASPrimitiveTraitCollection newTraitCollection = [self.node primitiveTraitCollection];
|
||||
for (ASCollectionElement *element in _visibleMap) {
|
||||
element.traitCollection = newTraitCollection;
|
||||
}
|
||||
|
@ -72,9 +72,9 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
*/
|
||||
@property (nonatomic, strong, nullable) UICollectionViewLayoutAttributes *layoutAttributes;
|
||||
|
||||
@property (weak, nullable) ASCollectionElement *collectionElement;
|
||||
@property (atomic, weak, nullable) ASCollectionElement *collectionElement;
|
||||
|
||||
@property (nonatomic, weak, nullable) ASDisplayNode *owningNode;
|
||||
@property (atomic, weak, nullable) id<ASRangeManagingNode> owningNode;
|
||||
|
||||
@property (nonatomic, assign) BOOL shouldUseUIKitCell;
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
//
|
||||
// ASTableViewTests.m
|
||||
// ASTableViewTests.mm
|
||||
// Texture
|
||||
//
|
||||
// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
|
||||
@ -61,7 +61,7 @@
|
||||
- (instancetype)__initWithFrame:(CGRect)frame style:(UITableViewStyle)style
|
||||
{
|
||||
|
||||
return [super _initWithFrame:frame style:style dataControllerClass:[ASTestDataController class] eventLog:nil];
|
||||
return [super _initWithFrame:frame style:style dataControllerClass:[ASTestDataController class] owningNode:nil eventLog:nil];
|
||||
}
|
||||
|
||||
- (ASTestDataController *)testDataController
|
||||
|
Loading…
x
Reference in New Issue
Block a user