mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-23 06:35:51 +00:00
Update to latest state
This commit is contained in:
@@ -7,73 +7,78 @@
|
||||
//
|
||||
|
||||
#import "ASPagerFlowLayout.h"
|
||||
#import "ASPagerNode.h"
|
||||
|
||||
@interface ASPagerFlowLayout ()
|
||||
|
||||
@property (strong, nonatomic) NSIndexPath *currentIndexPath;
|
||||
@property (weak, nonatomic) id<ASPagerFlowLayoutPageProvider> pageProvider;
|
||||
|
||||
@end
|
||||
|
||||
@implementation ASPagerFlowLayout
|
||||
|
||||
#pragma mark - Lifecycle
|
||||
|
||||
- (instancetype)initWithPageProvider:(id<ASPagerFlowLayoutPageProvider>)pageProvider
|
||||
{
|
||||
self = [super init];
|
||||
if (self == nil) { return self; }
|
||||
_pageProvider = pageProvider;
|
||||
return self;
|
||||
@implementation ASPagerFlowLayout {
|
||||
BOOL _didRotate;
|
||||
CGRect _cachedCollectionViewBounds;
|
||||
}
|
||||
|
||||
#pragma mark - UICollectionViewFlowLayout
|
||||
|
||||
- (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds
|
||||
- (CGPoint)targetContentOffsetForProposedContentOffset:(CGPoint)proposedContentOffset withScrollingVelocity:(CGPoint)velocity
|
||||
{
|
||||
CGRect oldBounds = self.collectionView.bounds;
|
||||
if (!CGSizeEqualToSize(oldBounds.size, newBounds.size)) {
|
||||
return YES;
|
||||
}
|
||||
NSInteger currentPage = ceil(proposedContentOffset.x / self.collectionView.bounds.size.width);
|
||||
self.currentIndexPath = [NSIndexPath indexPathForItem:currentPage inSection:0];
|
||||
|
||||
return NO;
|
||||
return [super targetContentOffsetForProposedContentOffset:proposedContentOffset withScrollingVelocity:velocity];
|
||||
}
|
||||
|
||||
|
||||
- (void)prepareForAnimatedBoundsChange:(CGRect)oldBounds
|
||||
{
|
||||
// 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) {
|
||||
self.currentIndexPath = attributes.indexPath;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
_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 (self.currentIndexPath) {
|
||||
return [self _targetContentOffsetForItemAtIndexPath:self.currentIndexPath proposedContentOffset:proposedContentOffset];
|
||||
}
|
||||
}
|
||||
|
||||
return [super targetContentOffsetForProposedContentOffset:proposedContentOffset];
|
||||
}
|
||||
|
||||
- (CGPoint)_targetContentOffsetForItemAtIndexPath:(NSIndexPath *)indexPath proposedContentOffset:(CGPoint)proposedContentOffset
|
||||
{
|
||||
if ([self _dataSourceIsEmpty]) {
|
||||
return proposedContentOffset;
|
||||
}
|
||||
|
||||
if (_pageProvider == nil || [self _visibleRectIsInvalid]) {
|
||||
return [super targetContentOffsetForProposedContentOffset:proposedContentOffset];
|
||||
}
|
||||
|
||||
NSIndexPath *indexPath = [NSIndexPath indexPathForItem:_pageProvider.currentPageIndex inSection:0];
|
||||
UICollectionViewLayoutAttributes *attributes = [self layoutAttributesForItemAtIndexPath:indexPath];
|
||||
CGFloat xOffset = (CGRectGetWidth(self.collectionView.bounds) - CGRectGetWidth(attributes.frame)) / 2;
|
||||
return CGPointMake(attributes.frame.origin.x - xOffset, proposedContentOffset.y);
|
||||
CGFloat currentPageXOffset = self.currentIndexPath.item * CGRectGetWidth(self.collectionView.bounds);
|
||||
return CGPointMake(currentPageXOffset, proposedContentOffset.y);
|
||||
}
|
||||
|
||||
#pragma mark - Helper
|
||||
|
||||
- (BOOL)_dataSourceIsEmpty
|
||||
{
|
||||
return ([self.collectionView numberOfSections] == 0 || [self.collectionView numberOfItemsInSection:0] == 0);
|
||||
}
|
||||
|
||||
- (CGRect)_visibleRect
|
||||
{
|
||||
CGRect visibleRect;
|
||||
visibleRect.origin = self.collectionView.contentOffset;
|
||||
visibleRect.size = self.collectionView.bounds.size;
|
||||
return visibleRect;
|
||||
}
|
||||
|
||||
- (BOOL)_visibleRectIsInvalid
|
||||
{
|
||||
return CGRectEqualToRect([self _visibleRect], CGRectZero);
|
||||
return ([self.collectionView numberOfSections] == 0 || [self.collectionView numberOfItemsInSection:0] == 0);
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
Reference in New Issue
Block a user