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

Commit fab98b3

Browse files
author
Adlai Holler
authored
Fix Pager Node Issues (#3028)
* Fix pager node and deprecate zeroContentInsets flag * Do it with the visible state callback * There we are * Put viewController in node debug description
1 parent aecd36a commit fab98b3

14 files changed

Lines changed: 271 additions & 67 deletions

AsyncDisplayKit.xcodeproj/project.pbxproj

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -327,6 +327,10 @@
327327
CC4C2A791D88E3BF0039ACAB /* ASTraceEvent.m in Sources */ = {isa = PBXBuildFile; fileRef = CC4C2A761D88E3BF0039ACAB /* ASTraceEvent.m */; };
328328
CC54A81C1D70079800296A24 /* ASDispatch.h in Headers */ = {isa = PBXBuildFile; fileRef = CC54A81B1D70077A00296A24 /* ASDispatch.h */; settings = {ATTRIBUTES = (Private, ); }; };
329329
CC54A81E1D7008B300296A24 /* ASDispatchTests.m in Sources */ = {isa = PBXBuildFile; fileRef = CC54A81D1D7008B300296A24 /* ASDispatchTests.m */; };
330+
CC55A70D1E529FA200594372 /* UIResponder+AsyncDisplayKit.h in Headers */ = {isa = PBXBuildFile; fileRef = CC55A70B1E529FA200594372 /* UIResponder+AsyncDisplayKit.h */; settings = {ATTRIBUTES = (Public, ); }; };
331+
CC55A70E1E529FA200594372 /* UIResponder+AsyncDisplayKit.m in Sources */ = {isa = PBXBuildFile; fileRef = CC55A70C1E529FA200594372 /* UIResponder+AsyncDisplayKit.m */; };
332+
CC55A7111E52A0F200594372 /* ASResponderChainEnumerator.h in Headers */ = {isa = PBXBuildFile; fileRef = CC55A70F1E52A0F200594372 /* ASResponderChainEnumerator.h */; };
333+
CC55A7121E52A0F200594372 /* ASResponderChainEnumerator.m in Sources */ = {isa = PBXBuildFile; fileRef = CC55A7101E52A0F200594372 /* ASResponderChainEnumerator.m */; };
330334
CC57EAF71E3939350034C595 /* ASCollectionView+Undeprecated.h in Headers */ = {isa = PBXBuildFile; fileRef = CC2E317F1DAC353700EEE891 /* ASCollectionView+Undeprecated.h */; settings = {ATTRIBUTES = (Private, ); }; };
331335
CC57EAF81E3939450034C595 /* ASTableView+Undeprecated.h in Headers */ = {isa = PBXBuildFile; fileRef = CC512B841DAC45C60054848E /* ASTableView+Undeprecated.h */; settings = {ATTRIBUTES = (Private, ); }; };
332336
CC58AA4B1E398E1D002C8CB4 /* ASBlockTypes.h in Headers */ = {isa = PBXBuildFile; fileRef = CC58AA4A1E398E1D002C8CB4 /* ASBlockTypes.h */; settings = {ATTRIBUTES = (Public, ); }; };
@@ -711,6 +715,10 @@
711715
CC512B841DAC45C60054848E /* ASTableView+Undeprecated.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "ASTableView+Undeprecated.h"; sourceTree = "<group>"; };
712716
CC54A81B1D70077A00296A24 /* ASDispatch.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ASDispatch.h; sourceTree = "<group>"; };
713717
CC54A81D1D7008B300296A24 /* ASDispatchTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = ASDispatchTests.m; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objc; };
718+
CC55A70B1E529FA200594372 /* UIResponder+AsyncDisplayKit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIResponder+AsyncDisplayKit.h"; sourceTree = "<group>"; };
719+
CC55A70C1E529FA200594372 /* UIResponder+AsyncDisplayKit.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIResponder+AsyncDisplayKit.m"; sourceTree = "<group>"; };
720+
CC55A70F1E52A0F200594372 /* ASResponderChainEnumerator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASResponderChainEnumerator.h; sourceTree = "<group>"; };
721+
CC55A7101E52A0F200594372 /* ASResponderChainEnumerator.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASResponderChainEnumerator.m; sourceTree = "<group>"; };
714722
CC57EAF91E394EA40034C595 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
715723
CC58AA4A1E398E1D002C8CB4 /* ASBlockTypes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASBlockTypes.h; sourceTree = "<group>"; };
716724
CC7FD9DC1BB5E962005CCB2B /* ASPhotosFrameworkImageRequest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASPhotosFrameworkImageRequest.h; sourceTree = "<group>"; };
@@ -927,6 +935,8 @@
927935
DB55C2651C641AE4004EDCF5 /* ASContextTransitioning.h */,
928936
68FC85E71CE29C7D00EDD713 /* ASVisibilityProtocols.h */,
929937
68FC85E81CE29C7D00EDD713 /* ASVisibilityProtocols.m */,
938+
CC55A70B1E529FA200594372 /* UIResponder+AsyncDisplayKit.h */,
939+
CC55A70C1E529FA200594372 /* UIResponder+AsyncDisplayKit.m */,
930940
690ED5911E36D118000627C0 /* tvOS */,
931941
DE89C1691DCEB9CC00D49D74 /* Debug */,
932942
058D09E1195D050800B7D73C /* Details */,
@@ -1120,6 +1130,8 @@
11201130
058D0A01195D050800B7D73C /* Private */ = {
11211131
isa = PBXGroup;
11221132
children = (
1133+
CC55A70F1E52A0F200594372 /* ASResponderChainEnumerator.h */,
1134+
CC55A7101E52A0F200594372 /* ASResponderChainEnumerator.m */,
11231135
6947B0BB1E36B4E30007C478 /* Layout */,
11241136
CCE04B2A1E313EDA006AEBBB /* Collection Data Adapter */,
11251137
058D0A03195D050800B7D73C /* _ASCoreAnimationExtras.h */,
@@ -1398,6 +1410,7 @@
13981410
B35062151B010EFD0018CF92 /* ASBatchContext.h in Headers */,
13991411
B35061F31B010EFD0018CF92 /* ASCellNode.h in Headers */,
14001412
34EFC7631B701CBF00AD841F /* ASCenterLayoutSpec.h in Headers */,
1413+
CC55A7111E52A0F200594372 /* ASResponderChainEnumerator.h in Headers */,
14011414
18C2ED7F1B9B7DE800F627B3 /* ASCollectionNode.h in Headers */,
14021415
B35061F51B010EFD0018CF92 /* ASCollectionView.h in Headers */,
14031416
ACE87A2C1D73696800D7FF06 /* ASSectionContext.h in Headers */,
@@ -1441,6 +1454,7 @@
14411454
254C6B771BF94DF4003EC431 /* ASTextKitAttributes.h in Headers */,
14421455
254C6B7D1BF94DF4003EC431 /* ASTextKitShadower.h in Headers */,
14431456
690ED58E1E36BCA6000627C0 /* ASLayoutElementStylePrivate.h in Headers */,
1457+
CC55A70D1E529FA200594372 /* UIResponder+AsyncDisplayKit.h in Headers */,
14441458
254C6B731BF94DF4003EC431 /* ASTextKitCoreTextAdditions.h in Headers */,
14451459
254C6B7A1BF94DF4003EC431 /* ASTextKitRenderer.h in Headers */,
14461460
69CB62AC1CB8165900024920 /* _ASDisplayViewAccessiblity.h in Headers */,
@@ -1827,6 +1841,7 @@
18271841
18C2ED831B9B7DE800F627B3 /* ASCollectionNode.mm in Sources */,
18281842
E55D86331CA8A14000A0C26F /* ASLayoutElement.mm in Sources */,
18291843
68FC85EC1CE29C7D00EDD713 /* ASVisibilityProtocols.m in Sources */,
1844+
CC55A7121E52A0F200594372 /* ASResponderChainEnumerator.m in Sources */,
18301845
68B8A4E41CBDB958007E4543 /* ASWeakProxy.m in Sources */,
18311846
9C70F20A1CDBE949007D6C76 /* ASTableNode.mm in Sources */,
18321847
69CB62AE1CB8165900024920 /* _ASDisplayViewAccessiblity.mm in Sources */,
@@ -1905,6 +1920,7 @@
19051920
254C6B871BF94F8A003EC431 /* ASTextKitEntityAttribute.m in Sources */,
19061921
34566CB31BC1213700715E6B /* ASPhotosFrameworkImageRequest.m in Sources */,
19071922
254C6B831BF94F8A003EC431 /* ASTextKitCoreTextAdditions.m in Sources */,
1923+
CC55A70E1E529FA200594372 /* UIResponder+AsyncDisplayKit.m in Sources */,
19081924
697796611D8AC8D3007E93D7 /* ASLayoutSpec+Subclasses.mm in Sources */,
19091925
B350623B1B010EFD0018CF92 /* NSMutableAttributedString+TextKitAdditions.m in Sources */,
19101926
044284FD1BAA365100D16268 /* UICollectionViewLayout+ASConvenience.m in Sources */,

AsyncDisplayKit/ASCollectionView.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,10 @@ NS_ASSUME_NONNULL_BEGIN
111111
*/
112112
@property (nonatomic, assign) BOOL inverted;
113113

114+
@end
115+
116+
@interface ASCollectionView (Deprecated)
117+
114118
/**
115119
* Forces the .contentInset to be UIEdgeInsetsZero.
116120
*
@@ -119,11 +123,7 @@ NS_ASSUME_NONNULL_BEGIN
119123
* automaticallyAdjustsScrollViewInsets, which may not be accessible. ASPagerNode uses this to ensure
120124
* its flow layout behaves predictably and does not log undefined layout warnings.
121125
*/
122-
@property (nonatomic) BOOL zeroContentInsets;
123-
124-
@end
125-
126-
@interface ASCollectionView (Deprecated)
126+
@property (nonatomic) BOOL zeroContentInsets ASDISPLAYNODE_DEPRECATED_MSG("Set automaticallyAdjustsScrollViewInsets=NO on your view controller instead.");
127127

128128
/**
129129
* The object that acts as the asynchronous delegate of the collection view

AsyncDisplayKit/ASCollectionView.mm

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#import <AsyncDisplayKit/_ASCollectionViewCell.h>
2727
#import <AsyncDisplayKit/_ASDisplayLayer.h>
2828
#import <AsyncDisplayKit/ASCollectionViewLayoutFacilitatorProtocol.h>
29+
#import <AsyncDisplayKit/ASPagerNode.h>
2930
#import <AsyncDisplayKit/ASSectionContext.h>
3031
#import <AsyncDisplayKit/ASCollectionView+Undeprecated.h>
3132
#import <AsyncDisplayKit/_ASHierarchyChangeSet.h>
@@ -93,6 +94,8 @@ @interface ASCollectionView () <ASRangeControllerDataSource, ASRangeControllerDe
9394
NSMutableSet *_registeredSupplementaryKinds;
9495

9596
CGPoint _deceleratingVelocity;
97+
98+
BOOL _zeroContentInsets;
9699

97100
ASCollectionViewInvalidationStyle _nextLayoutInvalidationStyle;
98101

@@ -584,6 +587,16 @@ - (ASRangeTuningParameters)tuningParametersForRangeMode:(ASLayoutRangeMode)range
584587
return [_rangeController tuningParametersForRangeMode:rangeMode rangeType:rangeType];
585588
}
586589

590+
- (void)setZeroContentInsets:(BOOL)zeroContentInsets
591+
{
592+
_zeroContentInsets = zeroContentInsets;
593+
}
594+
595+
- (BOOL)zeroContentInsets
596+
{
597+
return _zeroContentInsets;
598+
}
599+
587600
- (CGSize)calculatedSizeForNodeAtIndexPath:(NSIndexPath *)indexPath
588601
{
589602
return [[self nodeForItemAtIndexPath:indexPath] calculatedSize];
@@ -1911,19 +1924,11 @@ - (void)layer:(CALayer *)layer didChangeBoundsWithOldValue:(CGRect)oldBounds new
19111924
BOOL changedInNonScrollingDirection = (fixedHorizontally && newBounds.size.width != lastUsedSize.width) || (fixedVertically && newBounds.size.height != lastUsedSize.height);
19121925

19131926
if (changedInNonScrollingDirection) {
1914-
#pragma clang diagnostic push
1915-
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
1916-
// This actually doesn't perform an animation, but prevents the transaction block from being processed in the
1917-
// data controller's prevent animation block that would interrupt an interrupted relayout happening in an animation block
1918-
// ie. ASCollectionView bounds change on rotation or multi-tasking split view resize.
1919-
[self performBatchAnimated:YES updates:^{
1920-
[_dataController relayoutAllNodes];
1921-
} completion:nil];
1927+
[_dataController relayoutAllNodes];
1928+
[_dataController waitUntilAllUpdatesAreCommitted];
19221929
// We need to ensure the size requery is done before we update our layout.
1923-
[self waitUntilAllUpdatesAreCommitted];
19241930
[self.collectionViewLayout invalidateLayout];
19251931
}
1926-
#pragma clang diagnostic pop
19271932
}
19281933
}
19291934

AsyncDisplayKit/ASDisplayNode.mm

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
#import <AsyncDisplayKit/ASRunLoopQueue.h>
3737
#import <AsyncDisplayKit/ASTraitCollection.h>
3838
#import <AsyncDisplayKit/ASWeakProxy.h>
39+
#import <AsyncDisplayKit/ASResponderChainEnumerator.h>
3940

4041
/**
4142
* Assert if the current thread owns a mutex.
@@ -3784,6 +3785,20 @@ - (ASEventLog *)eventLog
37843785
[result addObject:@{ @"frameInWindow" : [NSValue valueWithCGRect:windowFrame] }];
37853786
}
37863787

3788+
// Attempt to find view controller.
3789+
// Note that the convenience method asdk_associatedViewController has an assertion
3790+
// that it's run on main. Since this is a debug method, let's bypass the assertion
3791+
// and run up the chain ourselves.
3792+
if (_view != nil) {
3793+
for (UIResponder *responder in [_view asdk_responderChainEnumerator]) {
3794+
UIViewController *vc = ASDynamicCast(responder, UIViewController);
3795+
if (vc) {
3796+
[result addObject:@{ @"viewController" : ASObjectDescriptionMakeTiny(vc) }];
3797+
break;
3798+
}
3799+
}
3800+
}
3801+
37873802
if (_view != nil) {
37883803
[result addObject:@{ @"frame" : [NSValue valueWithCGRect:_view.frame] }];
37893804
} else if (_layer != nil) {

AsyncDisplayKit/ASPagerFlowLayout.m

Lines changed: 55 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -11,62 +11,43 @@
1111
//
1212

1313
#import <AsyncDisplayKit/ASPagerFlowLayout.h>
14+
#import <AsyncDisplayKit/ASCellNode.h>
15+
#import <AsyncDisplayKit/ASCollectionView.h>
1416

1517
@interface ASPagerFlowLayout () {
16-
BOOL _didRotate;
17-
CGRect _cachedCollectionViewBounds;
18-
NSIndexPath *_currentIndexPath;
18+
__weak ASCellNode *_currentCellNode;
1919
}
2020

2121
@end
2222

2323
@implementation ASPagerFlowLayout
2424

25-
- (CGPoint)targetContentOffsetForProposedContentOffset:(CGPoint)proposedContentOffset withScrollingVelocity:(CGPoint)velocity
25+
- (ASCollectionView *)asCollectionView
2626
{
27-
NSInteger currentPage = ceil(proposedContentOffset.x / self.collectionView.bounds.size.width);
28-
_currentIndexPath = [NSIndexPath indexPathForItem:currentPage inSection:0];
29-
30-
return [super targetContentOffsetForProposedContentOffset:proposedContentOffset withScrollingVelocity:velocity];
27+
// Dynamic cast is too slow and not worth it.
28+
return (ASCollectionView *)self.collectionView;
3129
}
3230

33-
34-
- (void)prepareForAnimatedBoundsChange:(CGRect)oldBounds
31+
- (void)prepareLayout
3532
{
36-
// Cache the current page if a rotation did happen. This happens before the rotation animation
37-
// is occuring and the bounds changed so we use this as an opportunity to cache the current index path
38-
if (_cachedCollectionViewBounds.size.width != self.collectionView.bounds.size.width) {
39-
_cachedCollectionViewBounds = self.collectionView.bounds;
40-
41-
// Figurring out current page based on the old bounds visible space
42-
CGRect visibleRect = oldBounds;
43-
44-
CGFloat visibleXCenter = CGRectGetMidX(visibleRect);
45-
NSArray<UICollectionViewLayoutAttributes *> *layoutAttributes = [self layoutAttributesForElementsInRect:visibleRect];
46-
for (UICollectionViewLayoutAttributes *attributes in layoutAttributes) {
47-
if ([attributes representedElementCategory] == UICollectionElementCategoryCell && attributes.center.x == visibleXCenter) {
48-
_currentIndexPath = attributes.indexPath;
49-
break;
50-
}
51-
}
52-
53-
_didRotate = YES;
54-
}
55-
56-
[super prepareForAnimatedBoundsChange:oldBounds];
33+
[super prepareLayout];
34+
if (_currentCellNode == nil) {
35+
[self _updateCurrentNode];
36+
}
5737
}
38+
5839
- (CGPoint)targetContentOffsetForProposedContentOffset:(CGPoint)proposedContentOffset
5940
{
60-
// Don't mess around if the user is interacting with the page node. Although if just a rotation happened we should
61-
// try to use the current index path to not end up setting the target content offset to something in between pages
62-
if (_didRotate || (!self.collectionView.isDecelerating && !self.collectionView.isTracking)) {
63-
_didRotate = NO;
64-
if (_currentIndexPath) {
65-
return [self _targetContentOffsetForItemAtIndexPath:_currentIndexPath proposedContentOffset:proposedContentOffset];
66-
}
41+
// Don't mess around if the user is interacting with the page node. Although if just a rotation happened we should
42+
// try to use the current index path to not end up setting the target content offset to something in between pages
43+
if (!self.collectionView.decelerating && !self.collectionView.tracking) {
44+
NSIndexPath *indexPath = [self.asCollectionView indexPathForNode:_currentCellNode];
45+
if (indexPath) {
46+
return [self _targetContentOffsetForItemAtIndexPath:indexPath proposedContentOffset:proposedContentOffset];
6747
}
68-
69-
return [super targetContentOffsetForProposedContentOffset:proposedContentOffset];
48+
}
49+
50+
return [super targetContentOffsetForProposedContentOffset:proposedContentOffset];
7051
}
7152

7253
- (CGPoint)_targetContentOffsetForItemAtIndexPath:(NSIndexPath *)indexPath proposedContentOffset:(CGPoint)proposedContentOffset
@@ -75,19 +56,49 @@ - (CGPoint)_targetContentOffsetForItemAtIndexPath:(NSIndexPath *)indexPath propo
7556
return proposedContentOffset;
7657
}
7758

78-
UICollectionViewLayoutAttributes *attributes = [self layoutAttributesForItemAtIndexPath:_currentIndexPath];
59+
UICollectionViewLayoutAttributes *attributes = [self layoutAttributesForItemAtIndexPath:indexPath];
7960
if (attributes == nil) {
8061
return proposedContentOffset;
8162
}
82-
63+
8364
CGFloat xOffset = (CGRectGetWidth(self.collectionView.bounds) - CGRectGetWidth(attributes.frame)) / 2.0;
8465
return CGPointMake(attributes.frame.origin.x - xOffset, proposedContentOffset.y);
8566
}
8667

8768
- (BOOL)_dataSourceIsEmpty
8869
{
89-
return ([self.collectionView numberOfSections] == 0 ||
90-
[self.collectionView numberOfItemsInSection:0] == 0);
70+
return ([self.collectionView numberOfSections] == 0 ||
71+
[self.collectionView numberOfItemsInSection:0] == 0);
72+
}
73+
74+
- (void)_updateCurrentNode
75+
{
76+
// Never change node during an animated bounds change (rotation)
77+
// NOTE! Listening for -prepareForAnimatedBoundsChange and -finalizeAnimatedBoundsChange
78+
// isn't sufficient here! It's broken!
79+
NSArray *animKeys = self.collectionView.layer.animationKeys;
80+
for (NSString *key in animKeys) {
81+
if ([key hasPrefix:@"bounds"]) {
82+
return;
83+
}
84+
}
85+
86+
CGRect bounds = self.collectionView.bounds;
87+
CGRect rect = CGRectMake(CGRectGetMidX(bounds), CGRectGetMidY(bounds), 1, 1);
88+
89+
NSIndexPath *indexPath = [self layoutAttributesForElementsInRect:rect].firstObject.indexPath;
90+
if (indexPath) {
91+
ASCellNode *node = [self.asCollectionView nodeForItemAtIndexPath:indexPath];
92+
if (node) {
93+
_currentCellNode = node;
94+
}
95+
}
96+
}
97+
98+
- (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds
99+
{
100+
[self _updateCurrentNode];
101+
return [super shouldInvalidateLayoutForBoundsChange:newBounds];
91102
}
92103

93104
@end

AsyncDisplayKit/ASPagerNode.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,24 @@ NS_ASSUME_NONNULL_BEGIN
120120
*/
121121
- (NSInteger)indexOfPageWithNode:(ASCellNode *)node;
122122

123+
/**
124+
* Tells the pager node to allow its view controller to automatically adjust its content insets.
125+
*
126+
* @see UIViewController.automaticallyAdjustsScrollViewInsets
127+
*
128+
* @discussion ASPagerNode should usually not have its content insets automatically adjusted
129+
* because it scrolls horizontally, and flow layout will log errors because the pages
130+
* do not fit between the top & bottom insets of the collection view.
131+
*
132+
* The default value is NO, which means that ASPagerNode expects that its view controller will
133+
* have automaticallyAdjustsScrollViewInsets=NO.
134+
*
135+
* If this property is NO, but your view controller has automaticallyAdjustsScrollViewInsets=YES,
136+
* the pager node will set the property to NO and log a warning message. In the future,
137+
* the pager node will just log the warning, and you'll need to configure your view controller on your own.
138+
*/
139+
@property (nonatomic, assign) BOOL allowsAutomaticInsetsAdjustment;
140+
123141
@end
124142

125143
NS_ASSUME_NONNULL_END

AsyncDisplayKit/ASPagerNode.m

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,13 @@
1212

1313
#import <AsyncDisplayKit/ASPagerNode.h>
1414
#import <AsyncDisplayKit/ASDelegateProxy.h>
15+
#import <AsyncDisplayKit/ASDisplayNode+FrameworkPrivate.h>
1516
#import <AsyncDisplayKit/ASDisplayNode+Subclasses.h>
1617
#import <AsyncDisplayKit/ASPagerFlowLayout.h>
1718
#import <AsyncDisplayKit/ASAssert.h>
1819
#import <AsyncDisplayKit/ASCellNode.h>
1920
#import <AsyncDisplayKit/ASCollectionView+Undeprecated.h>
21+
#import <AsyncDisplayKit/UIResponder+AsyncDisplayKit.h>
2022

2123
@interface ASPagerNode () <ASCollectionDataSource, ASCollectionDelegate, ASCollectionDelegateFlowLayout, ASDelegateProxyInterceptor>
2224
{
@@ -80,11 +82,6 @@ - (void)didLoad
8082
cv.allowsSelection = NO;
8183
cv.showsVerticalScrollIndicator = NO;
8284
cv.showsHorizontalScrollIndicator = NO;
83-
84-
// Zeroing contentInset is important, as UIKit will set the top inset for the navigation bar even though
85-
// our view is only horizontally scrollable. This causes UICollectionViewFlowLayout to log a warning.
86-
// From here we cannot disable this directly (UIViewController's automaticallyAdjustsScrollViewInsets).
87-
cv.zeroContentInsets = YES;
8885

8986
ASRangeTuningParameters minimumRenderParams = { .leadingBufferScreenfuls = 0.0, .trailingBufferScreenfuls = 0.0 };
9087
ASRangeTuningParameters minimumPreloadParams = { .leadingBufferScreenfuls = 1.0, .trailingBufferScreenfuls = 1.0 };
@@ -211,4 +208,21 @@ - (void)proxyTargetHasDeallocated:(ASDelegateProxy *)proxy
211208
[self setDelegate:nil];
212209
}
213210

211+
- (void)didEnterVisibleState
212+
{
213+
[super didEnterVisibleState];
214+
215+
// Check that our view controller does not automatically set our content insets
216+
// It would be better to have a -didEnterHierarchy hook to put this in, but
217+
// such a hook doesn't currently exist, and in every use case I can imagine,
218+
// the pager is not hosted inside a range-managed node.
219+
if (_allowsAutomaticInsetsAdjustment == NO) {
220+
UIViewController *vc = [self.view asdk_associatedViewController];
221+
if (vc.automaticallyAdjustsScrollViewInsets) {
222+
NSLog(@"AsyncDisplayKit: ASPagerNode is setting automaticallyAdjustsScrollViewInsets=NO on its owning view controller %@. This automatic behavior will be disabled in the future. Set allowsAutomaticInsetsAdjustment=YES on the pager node to suppress this behavior.", vc);
223+
vc.automaticallyAdjustsScrollViewInsets = NO;
224+
}
225+
}
226+
}
227+
214228
@end

0 commit comments

Comments
 (0)