mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-22 22:25:57 +00:00
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
This commit is contained in:
@@ -327,6 +327,10 @@
|
||||
CC4C2A791D88E3BF0039ACAB /* ASTraceEvent.m in Sources */ = {isa = PBXBuildFile; fileRef = CC4C2A761D88E3BF0039ACAB /* ASTraceEvent.m */; };
|
||||
CC54A81C1D70079800296A24 /* ASDispatch.h in Headers */ = {isa = PBXBuildFile; fileRef = CC54A81B1D70077A00296A24 /* ASDispatch.h */; settings = {ATTRIBUTES = (Private, ); }; };
|
||||
CC54A81E1D7008B300296A24 /* ASDispatchTests.m in Sources */ = {isa = PBXBuildFile; fileRef = CC54A81D1D7008B300296A24 /* ASDispatchTests.m */; };
|
||||
CC55A70D1E529FA200594372 /* UIResponder+AsyncDisplayKit.h in Headers */ = {isa = PBXBuildFile; fileRef = CC55A70B1E529FA200594372 /* UIResponder+AsyncDisplayKit.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
CC55A70E1E529FA200594372 /* UIResponder+AsyncDisplayKit.m in Sources */ = {isa = PBXBuildFile; fileRef = CC55A70C1E529FA200594372 /* UIResponder+AsyncDisplayKit.m */; };
|
||||
CC55A7111E52A0F200594372 /* ASResponderChainEnumerator.h in Headers */ = {isa = PBXBuildFile; fileRef = CC55A70F1E52A0F200594372 /* ASResponderChainEnumerator.h */; };
|
||||
CC55A7121E52A0F200594372 /* ASResponderChainEnumerator.m in Sources */ = {isa = PBXBuildFile; fileRef = CC55A7101E52A0F200594372 /* ASResponderChainEnumerator.m */; };
|
||||
CC57EAF71E3939350034C595 /* ASCollectionView+Undeprecated.h in Headers */ = {isa = PBXBuildFile; fileRef = CC2E317F1DAC353700EEE891 /* ASCollectionView+Undeprecated.h */; settings = {ATTRIBUTES = (Private, ); }; };
|
||||
CC57EAF81E3939450034C595 /* ASTableView+Undeprecated.h in Headers */ = {isa = PBXBuildFile; fileRef = CC512B841DAC45C60054848E /* ASTableView+Undeprecated.h */; settings = {ATTRIBUTES = (Private, ); }; };
|
||||
CC58AA4B1E398E1D002C8CB4 /* ASBlockTypes.h in Headers */ = {isa = PBXBuildFile; fileRef = CC58AA4A1E398E1D002C8CB4 /* ASBlockTypes.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
@@ -711,6 +715,10 @@
|
||||
CC512B841DAC45C60054848E /* ASTableView+Undeprecated.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "ASTableView+Undeprecated.h"; sourceTree = "<group>"; };
|
||||
CC54A81B1D70077A00296A24 /* ASDispatch.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ASDispatch.h; sourceTree = "<group>"; };
|
||||
CC54A81D1D7008B300296A24 /* ASDispatchTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = ASDispatchTests.m; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objc; };
|
||||
CC55A70B1E529FA200594372 /* UIResponder+AsyncDisplayKit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIResponder+AsyncDisplayKit.h"; sourceTree = "<group>"; };
|
||||
CC55A70C1E529FA200594372 /* UIResponder+AsyncDisplayKit.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIResponder+AsyncDisplayKit.m"; sourceTree = "<group>"; };
|
||||
CC55A70F1E52A0F200594372 /* ASResponderChainEnumerator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASResponderChainEnumerator.h; sourceTree = "<group>"; };
|
||||
CC55A7101E52A0F200594372 /* ASResponderChainEnumerator.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASResponderChainEnumerator.m; sourceTree = "<group>"; };
|
||||
CC57EAF91E394EA40034C595 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
CC58AA4A1E398E1D002C8CB4 /* ASBlockTypes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASBlockTypes.h; sourceTree = "<group>"; };
|
||||
CC7FD9DC1BB5E962005CCB2B /* ASPhotosFrameworkImageRequest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASPhotosFrameworkImageRequest.h; sourceTree = "<group>"; };
|
||||
@@ -927,6 +935,8 @@
|
||||
DB55C2651C641AE4004EDCF5 /* ASContextTransitioning.h */,
|
||||
68FC85E71CE29C7D00EDD713 /* ASVisibilityProtocols.h */,
|
||||
68FC85E81CE29C7D00EDD713 /* ASVisibilityProtocols.m */,
|
||||
CC55A70B1E529FA200594372 /* UIResponder+AsyncDisplayKit.h */,
|
||||
CC55A70C1E529FA200594372 /* UIResponder+AsyncDisplayKit.m */,
|
||||
690ED5911E36D118000627C0 /* tvOS */,
|
||||
DE89C1691DCEB9CC00D49D74 /* Debug */,
|
||||
058D09E1195D050800B7D73C /* Details */,
|
||||
@@ -1120,6 +1130,8 @@
|
||||
058D0A01195D050800B7D73C /* Private */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
CC55A70F1E52A0F200594372 /* ASResponderChainEnumerator.h */,
|
||||
CC55A7101E52A0F200594372 /* ASResponderChainEnumerator.m */,
|
||||
6947B0BB1E36B4E30007C478 /* Layout */,
|
||||
CCE04B2A1E313EDA006AEBBB /* Collection Data Adapter */,
|
||||
058D0A03195D050800B7D73C /* _ASCoreAnimationExtras.h */,
|
||||
@@ -1398,6 +1410,7 @@
|
||||
B35062151B010EFD0018CF92 /* ASBatchContext.h in Headers */,
|
||||
B35061F31B010EFD0018CF92 /* ASCellNode.h in Headers */,
|
||||
34EFC7631B701CBF00AD841F /* ASCenterLayoutSpec.h in Headers */,
|
||||
CC55A7111E52A0F200594372 /* ASResponderChainEnumerator.h in Headers */,
|
||||
18C2ED7F1B9B7DE800F627B3 /* ASCollectionNode.h in Headers */,
|
||||
B35061F51B010EFD0018CF92 /* ASCollectionView.h in Headers */,
|
||||
ACE87A2C1D73696800D7FF06 /* ASSectionContext.h in Headers */,
|
||||
@@ -1441,6 +1454,7 @@
|
||||
254C6B771BF94DF4003EC431 /* ASTextKitAttributes.h in Headers */,
|
||||
254C6B7D1BF94DF4003EC431 /* ASTextKitShadower.h in Headers */,
|
||||
690ED58E1E36BCA6000627C0 /* ASLayoutElementStylePrivate.h in Headers */,
|
||||
CC55A70D1E529FA200594372 /* UIResponder+AsyncDisplayKit.h in Headers */,
|
||||
254C6B731BF94DF4003EC431 /* ASTextKitCoreTextAdditions.h in Headers */,
|
||||
254C6B7A1BF94DF4003EC431 /* ASTextKitRenderer.h in Headers */,
|
||||
69CB62AC1CB8165900024920 /* _ASDisplayViewAccessiblity.h in Headers */,
|
||||
@@ -1827,6 +1841,7 @@
|
||||
18C2ED831B9B7DE800F627B3 /* ASCollectionNode.mm in Sources */,
|
||||
E55D86331CA8A14000A0C26F /* ASLayoutElement.mm in Sources */,
|
||||
68FC85EC1CE29C7D00EDD713 /* ASVisibilityProtocols.m in Sources */,
|
||||
CC55A7121E52A0F200594372 /* ASResponderChainEnumerator.m in Sources */,
|
||||
68B8A4E41CBDB958007E4543 /* ASWeakProxy.m in Sources */,
|
||||
9C70F20A1CDBE949007D6C76 /* ASTableNode.mm in Sources */,
|
||||
69CB62AE1CB8165900024920 /* _ASDisplayViewAccessiblity.mm in Sources */,
|
||||
@@ -1905,6 +1920,7 @@
|
||||
254C6B871BF94F8A003EC431 /* ASTextKitEntityAttribute.m in Sources */,
|
||||
34566CB31BC1213700715E6B /* ASPhotosFrameworkImageRequest.m in Sources */,
|
||||
254C6B831BF94F8A003EC431 /* ASTextKitCoreTextAdditions.m in Sources */,
|
||||
CC55A70E1E529FA200594372 /* UIResponder+AsyncDisplayKit.m in Sources */,
|
||||
697796611D8AC8D3007E93D7 /* ASLayoutSpec+Subclasses.mm in Sources */,
|
||||
B350623B1B010EFD0018CF92 /* NSMutableAttributedString+TextKitAdditions.m in Sources */,
|
||||
044284FD1BAA365100D16268 /* UICollectionViewLayout+ASConvenience.m in Sources */,
|
||||
|
||||
@@ -111,6 +111,10 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
*/
|
||||
@property (nonatomic, assign) BOOL inverted;
|
||||
|
||||
@end
|
||||
|
||||
@interface ASCollectionView (Deprecated)
|
||||
|
||||
/**
|
||||
* Forces the .contentInset to be UIEdgeInsetsZero.
|
||||
*
|
||||
@@ -119,11 +123,7 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
* automaticallyAdjustsScrollViewInsets, which may not be accessible. ASPagerNode uses this to ensure
|
||||
* its flow layout behaves predictably and does not log undefined layout warnings.
|
||||
*/
|
||||
@property (nonatomic) BOOL zeroContentInsets;
|
||||
|
||||
@end
|
||||
|
||||
@interface ASCollectionView (Deprecated)
|
||||
@property (nonatomic) BOOL zeroContentInsets ASDISPLAYNODE_DEPRECATED_MSG("Set automaticallyAdjustsScrollViewInsets=NO on your view controller instead.");
|
||||
|
||||
/**
|
||||
* The object that acts as the asynchronous delegate of the collection view
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#import <AsyncDisplayKit/_ASCollectionViewCell.h>
|
||||
#import <AsyncDisplayKit/_ASDisplayLayer.h>
|
||||
#import <AsyncDisplayKit/ASCollectionViewLayoutFacilitatorProtocol.h>
|
||||
#import <AsyncDisplayKit/ASPagerNode.h>
|
||||
#import <AsyncDisplayKit/ASSectionContext.h>
|
||||
#import <AsyncDisplayKit/ASCollectionView+Undeprecated.h>
|
||||
#import <AsyncDisplayKit/_ASHierarchyChangeSet.h>
|
||||
@@ -94,6 +95,8 @@ static NSString * const kReuseIdentifier = @"_ASCollectionReuseIdentifier";
|
||||
|
||||
CGPoint _deceleratingVelocity;
|
||||
|
||||
BOOL _zeroContentInsets;
|
||||
|
||||
ASCollectionViewInvalidationStyle _nextLayoutInvalidationStyle;
|
||||
|
||||
/**
|
||||
@@ -584,6 +587,16 @@ static NSString * const kReuseIdentifier = @"_ASCollectionReuseIdentifier";
|
||||
return [_rangeController tuningParametersForRangeMode:rangeMode rangeType:rangeType];
|
||||
}
|
||||
|
||||
- (void)setZeroContentInsets:(BOOL)zeroContentInsets
|
||||
{
|
||||
_zeroContentInsets = zeroContentInsets;
|
||||
}
|
||||
|
||||
- (BOOL)zeroContentInsets
|
||||
{
|
||||
return _zeroContentInsets;
|
||||
}
|
||||
|
||||
- (CGSize)calculatedSizeForNodeAtIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
return [[self nodeForItemAtIndexPath:indexPath] calculatedSize];
|
||||
@@ -1911,19 +1924,11 @@ static NSString * const kReuseIdentifier = @"_ASCollectionReuseIdentifier";
|
||||
BOOL changedInNonScrollingDirection = (fixedHorizontally && newBounds.size.width != lastUsedSize.width) || (fixedVertically && newBounds.size.height != lastUsedSize.height);
|
||||
|
||||
if (changedInNonScrollingDirection) {
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
|
||||
// This actually doesn't perform an animation, but prevents the transaction block from being processed in the
|
||||
// data controller's prevent animation block that would interrupt an interrupted relayout happening in an animation block
|
||||
// ie. ASCollectionView bounds change on rotation or multi-tasking split view resize.
|
||||
[self performBatchAnimated:YES updates:^{
|
||||
[_dataController relayoutAllNodes];
|
||||
} completion:nil];
|
||||
[_dataController waitUntilAllUpdatesAreCommitted];
|
||||
// We need to ensure the size requery is done before we update our layout.
|
||||
[self waitUntilAllUpdatesAreCommitted];
|
||||
[self.collectionViewLayout invalidateLayout];
|
||||
}
|
||||
#pragma clang diagnostic pop
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
#import <AsyncDisplayKit/ASRunLoopQueue.h>
|
||||
#import <AsyncDisplayKit/ASTraitCollection.h>
|
||||
#import <AsyncDisplayKit/ASWeakProxy.h>
|
||||
#import <AsyncDisplayKit/ASResponderChainEnumerator.h>
|
||||
|
||||
/**
|
||||
* Assert if the current thread owns a mutex.
|
||||
@@ -3784,6 +3785,20 @@ ASDISPLAYNODE_INLINE BOOL nodeIsInRasterizedTree(ASDisplayNode *node) {
|
||||
[result addObject:@{ @"frameInWindow" : [NSValue valueWithCGRect:windowFrame] }];
|
||||
}
|
||||
|
||||
// Attempt to find view controller.
|
||||
// Note that the convenience method asdk_associatedViewController has an assertion
|
||||
// that it's run on main. Since this is a debug method, let's bypass the assertion
|
||||
// and run up the chain ourselves.
|
||||
if (_view != nil) {
|
||||
for (UIResponder *responder in [_view asdk_responderChainEnumerator]) {
|
||||
UIViewController *vc = ASDynamicCast(responder, UIViewController);
|
||||
if (vc) {
|
||||
[result addObject:@{ @"viewController" : ASObjectDescriptionMakeTiny(vc) }];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (_view != nil) {
|
||||
[result addObject:@{ @"frame" : [NSValue valueWithCGRect:_view.frame] }];
|
||||
} else if (_layer != nil) {
|
||||
|
||||
@@ -11,58 +11,39 @@
|
||||
//
|
||||
|
||||
#import <AsyncDisplayKit/ASPagerFlowLayout.h>
|
||||
#import <AsyncDisplayKit/ASCellNode.h>
|
||||
#import <AsyncDisplayKit/ASCollectionView.h>
|
||||
|
||||
@interface ASPagerFlowLayout () {
|
||||
BOOL _didRotate;
|
||||
CGRect _cachedCollectionViewBounds;
|
||||
NSIndexPath *_currentIndexPath;
|
||||
__weak ASCellNode *_currentCellNode;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation ASPagerFlowLayout
|
||||
|
||||
- (CGPoint)targetContentOffsetForProposedContentOffset:(CGPoint)proposedContentOffset withScrollingVelocity:(CGPoint)velocity
|
||||
- (ASCollectionView *)asCollectionView
|
||||
{
|
||||
NSInteger currentPage = ceil(proposedContentOffset.x / self.collectionView.bounds.size.width);
|
||||
_currentIndexPath = [NSIndexPath indexPathForItem:currentPage inSection:0];
|
||||
|
||||
return [super targetContentOffsetForProposedContentOffset:proposedContentOffset withScrollingVelocity:velocity];
|
||||
// Dynamic cast is too slow and not worth it.
|
||||
return (ASCollectionView *)self.collectionView;
|
||||
}
|
||||
|
||||
|
||||
- (void)prepareForAnimatedBoundsChange:(CGRect)oldBounds
|
||||
- (void)prepareLayout
|
||||
{
|
||||
// Cache the current page if a rotation did happen. This happens before the rotation animation
|
||||
// is occuring and the bounds changed so we use this as an opportunity to cache the current index path
|
||||
if (_cachedCollectionViewBounds.size.width != self.collectionView.bounds.size.width) {
|
||||
_cachedCollectionViewBounds = self.collectionView.bounds;
|
||||
|
||||
// Figurring out current page based on the old bounds visible space
|
||||
CGRect visibleRect = oldBounds;
|
||||
|
||||
CGFloat visibleXCenter = CGRectGetMidX(visibleRect);
|
||||
NSArray<UICollectionViewLayoutAttributes *> *layoutAttributes = [self layoutAttributesForElementsInRect:visibleRect];
|
||||
for (UICollectionViewLayoutAttributes *attributes in layoutAttributes) {
|
||||
if ([attributes representedElementCategory] == UICollectionElementCategoryCell && attributes.center.x == visibleXCenter) {
|
||||
_currentIndexPath = attributes.indexPath;
|
||||
break;
|
||||
[super prepareLayout];
|
||||
if (_currentCellNode == nil) {
|
||||
[self _updateCurrentNode];
|
||||
}
|
||||
}
|
||||
|
||||
_didRotate = YES;
|
||||
}
|
||||
|
||||
[super prepareForAnimatedBoundsChange:oldBounds];
|
||||
}
|
||||
|
||||
- (CGPoint)targetContentOffsetForProposedContentOffset:(CGPoint)proposedContentOffset
|
||||
{
|
||||
// Don't mess around if the user is interacting with the page node. Although if just a rotation happened we should
|
||||
// try to use the current index path to not end up setting the target content offset to something in between pages
|
||||
if (_didRotate || (!self.collectionView.isDecelerating && !self.collectionView.isTracking)) {
|
||||
_didRotate = NO;
|
||||
if (_currentIndexPath) {
|
||||
return [self _targetContentOffsetForItemAtIndexPath:_currentIndexPath proposedContentOffset:proposedContentOffset];
|
||||
if (!self.collectionView.decelerating && !self.collectionView.tracking) {
|
||||
NSIndexPath *indexPath = [self.asCollectionView indexPathForNode:_currentCellNode];
|
||||
if (indexPath) {
|
||||
return [self _targetContentOffsetForItemAtIndexPath:indexPath proposedContentOffset:proposedContentOffset];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -75,7 +56,7 @@
|
||||
return proposedContentOffset;
|
||||
}
|
||||
|
||||
UICollectionViewLayoutAttributes *attributes = [self layoutAttributesForItemAtIndexPath:_currentIndexPath];
|
||||
UICollectionViewLayoutAttributes *attributes = [self layoutAttributesForItemAtIndexPath:indexPath];
|
||||
if (attributes == nil) {
|
||||
return proposedContentOffset;
|
||||
}
|
||||
@@ -90,4 +71,34 @@
|
||||
[self.collectionView numberOfItemsInSection:0] == 0);
|
||||
}
|
||||
|
||||
- (void)_updateCurrentNode
|
||||
{
|
||||
// Never change node during an animated bounds change (rotation)
|
||||
// NOTE! Listening for -prepareForAnimatedBoundsChange and -finalizeAnimatedBoundsChange
|
||||
// isn't sufficient here! It's broken!
|
||||
NSArray *animKeys = self.collectionView.layer.animationKeys;
|
||||
for (NSString *key in animKeys) {
|
||||
if ([key hasPrefix:@"bounds"]) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
CGRect bounds = self.collectionView.bounds;
|
||||
CGRect rect = CGRectMake(CGRectGetMidX(bounds), CGRectGetMidY(bounds), 1, 1);
|
||||
|
||||
NSIndexPath *indexPath = [self layoutAttributesForElementsInRect:rect].firstObject.indexPath;
|
||||
if (indexPath) {
|
||||
ASCellNode *node = [self.asCollectionView nodeForItemAtIndexPath:indexPath];
|
||||
if (node) {
|
||||
_currentCellNode = node;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds
|
||||
{
|
||||
[self _updateCurrentNode];
|
||||
return [super shouldInvalidateLayoutForBoundsChange:newBounds];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -120,6 +120,24 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
*/
|
||||
- (NSInteger)indexOfPageWithNode:(ASCellNode *)node;
|
||||
|
||||
/**
|
||||
* Tells the pager node to allow its view controller to automatically adjust its content insets.
|
||||
*
|
||||
* @see UIViewController.automaticallyAdjustsScrollViewInsets
|
||||
*
|
||||
* @discussion ASPagerNode should usually not have its content insets automatically adjusted
|
||||
* because it scrolls horizontally, and flow layout will log errors because the pages
|
||||
* do not fit between the top & bottom insets of the collection view.
|
||||
*
|
||||
* The default value is NO, which means that ASPagerNode expects that its view controller will
|
||||
* have automaticallyAdjustsScrollViewInsets=NO.
|
||||
*
|
||||
* If this property is NO, but your view controller has automaticallyAdjustsScrollViewInsets=YES,
|
||||
* the pager node will set the property to NO and log a warning message. In the future,
|
||||
* the pager node will just log the warning, and you'll need to configure your view controller on your own.
|
||||
*/
|
||||
@property (nonatomic, assign) BOOL allowsAutomaticInsetsAdjustment;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
|
||||
@@ -12,11 +12,13 @@
|
||||
|
||||
#import <AsyncDisplayKit/ASPagerNode.h>
|
||||
#import <AsyncDisplayKit/ASDelegateProxy.h>
|
||||
#import <AsyncDisplayKit/ASDisplayNode+FrameworkPrivate.h>
|
||||
#import <AsyncDisplayKit/ASDisplayNode+Subclasses.h>
|
||||
#import <AsyncDisplayKit/ASPagerFlowLayout.h>
|
||||
#import <AsyncDisplayKit/ASAssert.h>
|
||||
#import <AsyncDisplayKit/ASCellNode.h>
|
||||
#import <AsyncDisplayKit/ASCollectionView+Undeprecated.h>
|
||||
#import <AsyncDisplayKit/UIResponder+AsyncDisplayKit.h>
|
||||
|
||||
@interface ASPagerNode () <ASCollectionDataSource, ASCollectionDelegate, ASCollectionDelegateFlowLayout, ASDelegateProxyInterceptor>
|
||||
{
|
||||
@@ -81,11 +83,6 @@
|
||||
cv.showsVerticalScrollIndicator = NO;
|
||||
cv.showsHorizontalScrollIndicator = NO;
|
||||
|
||||
// Zeroing contentInset is important, as UIKit will set the top inset for the navigation bar even though
|
||||
// our view is only horizontally scrollable. This causes UICollectionViewFlowLayout to log a warning.
|
||||
// From here we cannot disable this directly (UIViewController's automaticallyAdjustsScrollViewInsets).
|
||||
cv.zeroContentInsets = YES;
|
||||
|
||||
ASRangeTuningParameters minimumRenderParams = { .leadingBufferScreenfuls = 0.0, .trailingBufferScreenfuls = 0.0 };
|
||||
ASRangeTuningParameters minimumPreloadParams = { .leadingBufferScreenfuls = 1.0, .trailingBufferScreenfuls = 1.0 };
|
||||
[self setTuningParameters:minimumRenderParams forRangeMode:ASLayoutRangeModeMinimum rangeType:ASLayoutRangeTypeDisplay];
|
||||
@@ -211,4 +208,21 @@
|
||||
[self setDelegate:nil];
|
||||
}
|
||||
|
||||
- (void)didEnterVisibleState
|
||||
{
|
||||
[super didEnterVisibleState];
|
||||
|
||||
// Check that our view controller does not automatically set our content insets
|
||||
// It would be better to have a -didEnterHierarchy hook to put this in, but
|
||||
// such a hook doesn't currently exist, and in every use case I can imagine,
|
||||
// the pager is not hosted inside a range-managed node.
|
||||
if (_allowsAutomaticInsetsAdjustment == NO) {
|
||||
UIViewController *vc = [self.view asdk_associatedViewController];
|
||||
if (vc.automaticallyAdjustsScrollViewInsets) {
|
||||
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);
|
||||
vc.automaticallyAdjustsScrollViewInsets = NO;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -106,6 +106,7 @@
|
||||
#import <AsyncDisplayKit/UIImage+ASConvenience.h>
|
||||
#import <AsyncDisplayKit/NSArray+Diffing.h>
|
||||
#import <AsyncDisplayKit/ASObjectDescriptionHelpers.h>
|
||||
#import <AsyncDisplayKit/UIResponder+AsyncDisplayKit.h>
|
||||
|
||||
#import <AsyncDisplayKit/AsyncDisplayKit+Debug.h>
|
||||
#import <AsyncDisplayKit/ASDisplayNode+Deprecated.h>
|
||||
|
||||
28
AsyncDisplayKit/Private/ASResponderChainEnumerator.h
Normal file
28
AsyncDisplayKit/Private/ASResponderChainEnumerator.h
Normal file
@@ -0,0 +1,28 @@
|
||||
//
|
||||
// ASResponderChainEnumerator.h
|
||||
// AsyncDisplayKit
|
||||
//
|
||||
// Created by Adlai Holler on 2/13/17.
|
||||
// Copyright © 2017 Facebook. All rights reserved.
|
||||
//
|
||||
|
||||
#import <UIKit/UIResponder.h>
|
||||
#import <AsyncDisplayKit/ASBaseDefines.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
AS_SUBCLASSING_RESTRICTED
|
||||
@interface ASResponderChainEnumerator : NSEnumerator
|
||||
|
||||
- (instancetype)initWithResponder:(UIResponder *)responder;
|
||||
|
||||
@end
|
||||
|
||||
@interface UIResponder (ASResponderChainEnumerator)
|
||||
|
||||
- (ASResponderChainEnumerator *)asdk_responderChainEnumerator;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
41
AsyncDisplayKit/Private/ASResponderChainEnumerator.m
Normal file
41
AsyncDisplayKit/Private/ASResponderChainEnumerator.m
Normal file
@@ -0,0 +1,41 @@
|
||||
//
|
||||
// ASResponderChainEnumerator.m
|
||||
// AsyncDisplayKit
|
||||
//
|
||||
// Created by Adlai Holler on 2/13/17.
|
||||
// Copyright © 2017 Facebook. All rights reserved.
|
||||
//
|
||||
|
||||
#import "ASResponderChainEnumerator.h"
|
||||
|
||||
@implementation ASResponderChainEnumerator {
|
||||
UIResponder *_currentResponder;
|
||||
}
|
||||
|
||||
- (instancetype)initWithResponder:(UIResponder *)responder
|
||||
{
|
||||
if (self = [super init]) {
|
||||
_currentResponder = responder;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
#pragma mark - NSEnumerator
|
||||
|
||||
- (id)nextObject
|
||||
{
|
||||
id result = [_currentResponder nextResponder];
|
||||
_currentResponder = result;
|
||||
return result;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation UIResponder (ASResponderChainEnumerator)
|
||||
|
||||
- (NSEnumerator *)asdk_responderChainEnumerator
|
||||
{
|
||||
return [[ASResponderChainEnumerator alloc] initWithResponder:self];
|
||||
}
|
||||
|
||||
@end
|
||||
24
AsyncDisplayKit/UIResponder+AsyncDisplayKit.h
Normal file
24
AsyncDisplayKit/UIResponder+AsyncDisplayKit.h
Normal file
@@ -0,0 +1,24 @@
|
||||
//
|
||||
// UIResponder+AsyncDisplayKit.h
|
||||
// AsyncDisplayKit
|
||||
//
|
||||
// Created by Adlai Holler on 2/13/17.
|
||||
// Copyright © 2017 Facebook. All rights reserved.
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface UIResponder (AsyncDisplayKit)
|
||||
|
||||
/**
|
||||
* The nearest view controller above this responder, if one exists.
|
||||
*
|
||||
* This property must be accessed on the main thread.
|
||||
*/
|
||||
@property (nonatomic, nullable, readonly) __kindof UIViewController *asdk_associatedViewController;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
31
AsyncDisplayKit/UIResponder+AsyncDisplayKit.m
Normal file
31
AsyncDisplayKit/UIResponder+AsyncDisplayKit.m
Normal file
@@ -0,0 +1,31 @@
|
||||
//
|
||||
// UIResponder+AsyncDisplayKit.m
|
||||
// AsyncDisplayKit
|
||||
//
|
||||
// Created by Adlai Holler on 2/13/17.
|
||||
// Copyright © 2017 Facebook. All rights reserved.
|
||||
//
|
||||
|
||||
#import "UIResponder+AsyncDisplayKit.h"
|
||||
|
||||
#import <AsyncDisplayKit/ASAssert.h>
|
||||
#import <AsyncDisplayKit/ASBaseDefines.h>
|
||||
#import <AsyncDisplayKit/ASResponderChainEnumerator.h>
|
||||
|
||||
@implementation UIResponder (AsyncDisplayKit)
|
||||
|
||||
- (__kindof UIViewController *)asdk_associatedViewController
|
||||
{
|
||||
ASDisplayNodeAssertMainThread();
|
||||
|
||||
for (UIResponder *responder in [self asdk_responderChainEnumerator]) {
|
||||
UIViewController *vc = ASDynamicCast(responder, UIViewController);
|
||||
if (vc) {
|
||||
return vc;
|
||||
}
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -21,9 +21,9 @@
|
||||
|
||||
@implementation PageNode
|
||||
|
||||
- (ASLayout *)calculateLayoutThatFits:(ASSizeRange)constrainedSize
|
||||
- (CGSize)calculateSizeThatFits:(CGSize)constrainedSize
|
||||
{
|
||||
return [ASLayout layoutWithLayoutElement:self size:constrainedSize.max];
|
||||
return constrainedSize;
|
||||
}
|
||||
|
||||
- (void)fetchData
|
||||
|
||||
@@ -46,7 +46,7 @@ static UIColor *randomColor() {
|
||||
|
||||
self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"Next" style:UIBarButtonItemStylePlain target:self action:@selector(scrollToNextPage:)];
|
||||
self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"Previous" style:UIBarButtonItemStylePlain target:self action:@selector(scrollToPreviousPage:)];
|
||||
|
||||
self.automaticallyAdjustsScrollViewInsets = NO;
|
||||
return self;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user