Skip to content
This repository was archived by the owner on Feb 2, 2023. It is now read-only.

Commit 95e28d6

Browse files
committed
Merge pull request #1015 from facebook/CollectionTableLayers
Use _ASDisplayLayer for both ASTableView and ASCollectionView. zeroContentInsets to fix UIKit.
2 parents b1b9ad2 + 051f1f6 commit 95e28d6

5 files changed

Lines changed: 62 additions & 25 deletions

File tree

AsyncDisplayKit/ASCollectionView.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,16 @@ NS_ASSUME_NONNULL_BEGIN
288288
*/
289289
- (void)clearFetchedData;
290290

291+
/**
292+
* Forces the .contentInset to be UIEdgeInsetsZero.
293+
*
294+
* @discussion By default, UIKit sets the top inset to the navigation bar height, even for horizontally
295+
* scrolling views. This can only be disabled by setting a property on the containing UIViewController,
296+
* automaticallyAdjustsScrollViewInsets, which may not be accessible. ASPagerNode uses this to ensure
297+
* its flow layout behaves predictably and does not log undefined layout warnings.
298+
*/
299+
@property (nonatomic) BOOL zeroContentInsets;
300+
291301
@end
292302

293303

AsyncDisplayKit/ASCollectionView.mm

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#import "ASInternalHelpers.h"
1818
#import "ASRangeController.h"
1919
#import "UICollectionViewLayout+ASConvenience.h"
20+
#import "_ASDisplayLayer.h"
2021

2122
static const NSUInteger kASCollectionViewAnimationNone = UITableViewRowAnimationNone;
2223
static const ASSizeRange kInvalidSizeRange = {CGSizeZero, CGSizeZero};
@@ -113,6 +114,12 @@ - (instancetype)_initWithCollectionView:(ASCollectionView *)collectionView;
113114

114115
@implementation ASCollectionView
115116

117+
// Using _ASDisplayLayer ensures things like -layout are properly forwarded to ASCollectionNode.
118+
+ (Class)layerClass
119+
{
120+
return [_ASDisplayLayer class];
121+
}
122+
116123
#pragma mark -
117124
#pragma mark Lifecycle.
118125

@@ -221,7 +228,6 @@ - (ASCollectionViewFlowLayoutInspector *)flowLayoutInspector
221228

222229
- (void)reloadDataWithCompletion:(void (^)())completion
223230
{
224-
ASDisplayNodeAssert(self.asyncDelegate, @"ASCollectionView's asyncDelegate property must be set.");
225231
ASPerformBlockOnMainThread(^{
226232
_superIsPendingDataLoad = YES;
227233
[super reloadData];
@@ -557,6 +563,10 @@ - (void)collectionView:(UICollectionView *)collectionView didEndDisplayingCell:(
557563

558564
- (void)layoutSubviews
559565
{
566+
if (_zeroContentInsets) {
567+
self.contentInset = UIEdgeInsetsZero;
568+
}
569+
560570
if (! CGSizeEqualToSize(_maxSizeForNodesConstrainedSize, self.bounds.size)) {
561571
_maxSizeForNodesConstrainedSize = self.bounds.size;
562572

AsyncDisplayKit/ASPagerNode.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717
- (ASCellNode *)pagerNode:(ASPagerNode *)pagerNode nodeAtIndex:(NSInteger)index;
1818
@end
1919

20+
// WARNING: ASPagerNode is new in AsyncDisplayKit 1.9.4 and not yet widely tested.
21+
// Details of its API or behavior may change in future releases
2022
@interface ASPagerNode : ASCollectionNode
2123

2224
// Configures a default horizontal, paging flow layout with 0 inter-item spacing.

AsyncDisplayKit/ASPagerNode.m

Lines changed: 32 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@
1010
#import "ASDelegateProxy.h"
1111
#import "ASDisplayNode+Subclasses.h"
1212

13-
@interface ASPagerNode () <ASCollectionDataSource, ASCollectionViewDelegateFlowLayout, ASDelegateProxyInterceptor> {
13+
@interface ASPagerNode () <ASCollectionDataSource, ASCollectionViewDelegateFlowLayout, ASDelegateProxyInterceptor>
14+
{
1415
UICollectionViewFlowLayout *_flowLayout;
1516
ASPagerNodeProxy *_proxy;
1617
id <ASPagerNodeDataSource> _pagerDataSource;
@@ -46,25 +47,6 @@ - (instancetype)initWithFlowLayout:(UICollectionViewFlowLayout *)flowLayout
4647
return self;
4748
}
4849

49-
- (void)setDataSource:(id <ASPagerNodeDataSource>)pagerDataSource
50-
{
51-
if (pagerDataSource != _pagerDataSource) {
52-
_pagerDataSource = pagerDataSource;
53-
_proxy = pagerDataSource ? [[ASPagerNodeProxy alloc] initWithTarget:pagerDataSource interceptor:self] : nil;
54-
super.dataSource = (id <ASCollectionDataSource>)_proxy;
55-
}
56-
}
57-
58-
- (void)proxyTargetHasDeallocated:(ASDelegateProxy *)proxy
59-
{
60-
[self setDataSource:nil];
61-
}
62-
63-
- (id <ASPagerNodeDataSource>)dataSource
64-
{
65-
return _pagerDataSource;
66-
}
67-
6850
- (void)didLoad
6951
{
7052
[super didLoad];
@@ -77,6 +59,11 @@ - (void)didLoad
7759
cv.showsHorizontalScrollIndicator = NO;
7860
cv.scrollsToTop = NO;
7961

62+
// Zeroing contentInset is important, as UIKit will set the top inset for the navigation bar even though
63+
// our view is only horizontally scrollable. This causes UICollectionViewFlowLayout to log a warning.
64+
// From here we cannot disable this directly (UIViewController's automaticallyAdjustsScrollViewInsets).
65+
cv.zeroContentInsets = YES;
66+
8067
ASRangeTuningParameters preloadParams = { .leadingBufferScreenfuls = 2.0, .trailingBufferScreenfuls = 2.0 };
8168
ASRangeTuningParameters renderParams = { .leadingBufferScreenfuls = 1.0, .trailingBufferScreenfuls = 1.0 };
8269
[self setTuningParameters:preloadParams forRangeType:ASLayoutRangeTypePreload];
@@ -95,13 +82,14 @@ - (void)scrollToPageAtIndex:(NSInteger)index animated:(BOOL)animated
9582

9683
- (ASCellNode *)collectionView:(ASCollectionView *)collectionView nodeForItemAtIndexPath:(NSIndexPath *)indexPath
9784
{
98-
ASDisplayNodeAssert(_pagerDataSource != nil, @"ASPagerNode must have a data source to load paging nodes");
99-
return [_pagerDataSource pagerNode:self nodeAtIndex:indexPath.item];
85+
ASDisplayNodeAssert(_pagerDataSource != nil, @"ASPagerNode must have a data source to load nodes to display");
86+
ASCellNode *pageNode = [_pagerDataSource pagerNode:self nodeAtIndex:indexPath.item];
87+
return pageNode;
10088
}
10189

10290
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
10391
{
104-
ASDisplayNodeAssert(_pagerDataSource != nil, @"ASPagerNode must have a data source to load paging nodes");
92+
ASDisplayNodeAssert(_pagerDataSource != nil, @"ASPagerNode must have a data source to load nodes to display");
10593
return [_pagerDataSource numberOfPagesInPagerNode:self];
10694
}
10795

@@ -110,4 +98,25 @@ - (ASSizeRange)collectionView:(ASCollectionView *)collectionView constrainedSize
11098
return ASSizeRangeMake(CGSizeZero, self.view.bounds.size);
11199
}
112100

101+
#pragma mark - Data Source Proxy
102+
103+
- (id <ASPagerNodeDataSource>)dataSource
104+
{
105+
return _pagerDataSource;
106+
}
107+
108+
- (void)setDataSource:(id <ASPagerNodeDataSource>)pagerDataSource
109+
{
110+
if (pagerDataSource != _pagerDataSource) {
111+
_pagerDataSource = pagerDataSource;
112+
_proxy = pagerDataSource ? [[ASPagerNodeProxy alloc] initWithTarget:pagerDataSource interceptor:self] : nil;
113+
super.dataSource = (id <ASCollectionDataSource>)_proxy;
114+
}
115+
}
116+
117+
- (void)proxyTargetHasDeallocated:(ASDelegateProxy *)proxy
118+
{
119+
[self setDataSource:nil];
120+
}
121+
113122
@end

AsyncDisplayKit/ASTableView.mm

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#import "ASLayout.h"
1919
#import "ASLayoutController.h"
2020
#import "ASRangeController.h"
21+
#import "_ASDisplayLayer.h"
2122

2223
#import <CoreFoundation/CoreFoundation.h>
2324

@@ -120,6 +121,12 @@ @interface ASTableView () <ASRangeControllerDataSource, ASRangeControllerDelegat
120121

121122
@implementation ASTableView
122123

124+
// Using _ASDisplayLayer ensures things like -layout are properly forwarded to ASTableNode.
125+
+ (Class)layerClass
126+
{
127+
return [_ASDisplayLayer class];
128+
}
129+
123130
+ (Class)dataControllerClass
124131
{
125132
return [ASChangeSetDataController class];
@@ -280,7 +287,6 @@ - (void)proxyTargetHasDeallocated:(ASDelegateProxy *)proxy
280287

281288
- (void)reloadDataWithCompletion:(void (^)())completion
282289
{
283-
ASDisplayNodeAssert(self.asyncDelegate, @"ASTableView's asyncDelegate property must be set.");
284290
ASPerformBlockOnMainThread(^{
285291
[super reloadData];
286292
});

0 commit comments

Comments
 (0)