我在我的UIViewController中使用UICollectionView.
我的collectionview属性设置如下.
现在我希望滚动后单元格在屏幕上居中!选项1:
选项2:
我需要做什么来实现选项2?
更新:
最后我使用下面的代码作为滚动与其他答案不顺利.
- (CGPoint)targetContentOffsetForProposedContentOffset:(CGPoint)proposedContentOffset withScrollingVelocity:(CGPoint)velocity { CGFloat offsetAdjustment = MAXFLOAT; CGFloat horizontalCenter = proposedContentOffset.x + (CGRectGetWidth(self.collectionView.bounds) / 2.0); CGRect targetRect = CGRectMake(proposedContentOffset.x, 0.0, self.collectionView.bounds.size.width, self.collectionView.bounds.size.height); NSArray* array = [super layoutAttributesForElementsInRect:targetRect]; for (UICollectionViewLayoutAttributes* layoutAttributes in array) { CGFloat itemHorizontalCenter = layoutAttributes.center.x; if (ABS(itemHorizontalCenter - horizontalCenter) < ABS(offsetAdjustment)) { offsetAdjustment = itemHorizontalCenter - horizontalCenter; } } return CGPointMake(proposedContentOffset.x + offsetAdjustment, proposedContentOffset.y); }
Dmitry Zhuko.. 15
您可以覆盖子类中的targetContentOffsetForProposedContentOffset:withScrollingVelocity:
方法UICollectionViewLayout
并计算您的偏移量,如下所示:
@property (nonatomic, assign) CGFloat previousOffset; @property (nonatomic, assign) NSInteger currentPage; ... - (CGPoint)targetContentOffsetForProposedContentOffset:(CGPoint)proposedContentOffset withScrollingVelocity:(CGPoint)velocity { NSInteger itemsCount = [self.collectionView.dataSource collectionView:self.collectionView numberOfItemsInSection:0]; // Imitating paging behaviour // Check previous offset and scroll direction if ((self.previousOffset > self.collectionView.contentOffset.x) && (velocity.x < 0.0f)) { self.currentPage = MAX(self.currentPage - 1, 0); } else if ((self.previousOffset < self.collectionView.contentOffset.x) && (velocity.x > 0.0f)) { self.currentPage = MIN(self.currentPage + 1, itemsCount - 1); } // Update offset by using item size + spacing CGFloat updatedOffset = (self.itemSize.width + self.minimumInteritemSpacing) * self.currentPage; self.previousOffset = updatedOffset; return CGPointMake(updatedOffset, proposedContentOffset.y); }
编辑:感谢您指出这一点,忘了说您必须先禁用分页:
self.collectionView.pagingEnabled = NO;
更新:附加Swift 4.2版本
... collectionView.isPagingEnabled = false ... class YourCollectionLayoutSubclass: UICollectionViewFlowLayout { private var previousOffset: CGFloat = 0 private var currentPage: Int = 0 override func targetContentOffset(forProposedContentOffset proposedContentOffset: CGPoint, withScrollingVelocity velocity: CGPoint) -> CGPoint { guard let collectionView = collectionView else { return super.targetContentOffset(forProposedContentOffset: proposedContentOffset, withScrollingVelocity: velocity) } let itemsCount = collectionView.numberOfItems(inSection: 0) // Imitating paging behaviour // Check previous offset and scroll direction if previousOffset > collectionView.contentOffset.x && velocity.x < 0 { currentPage = max(currentPage - 1, 0) } else if previousOffset < collectionView.contentOffset.x && velocity.x > 0 { currentPage = min(currentPage + 1, itemsCount - 1) } // Update offset by using item size + spacing let updatedOffset = (itemSize.width + minimumInteritemSpacing) * CGFloat(currentPage) previousOffset = updatedOffset return CGPoint(x: updatedOffset, y: proposedContentOffset.y) } }
小智.. 9
你可以使用代码
self.collectionView.scrollToItem(at: indexPath, at: .centeredHorizontally, animated: true)
您可以覆盖子类中的targetContentOffsetForProposedContentOffset:withScrollingVelocity:
方法UICollectionViewLayout
并计算您的偏移量,如下所示:
@property (nonatomic, assign) CGFloat previousOffset; @property (nonatomic, assign) NSInteger currentPage; ... - (CGPoint)targetContentOffsetForProposedContentOffset:(CGPoint)proposedContentOffset withScrollingVelocity:(CGPoint)velocity { NSInteger itemsCount = [self.collectionView.dataSource collectionView:self.collectionView numberOfItemsInSection:0]; // Imitating paging behaviour // Check previous offset and scroll direction if ((self.previousOffset > self.collectionView.contentOffset.x) && (velocity.x < 0.0f)) { self.currentPage = MAX(self.currentPage - 1, 0); } else if ((self.previousOffset < self.collectionView.contentOffset.x) && (velocity.x > 0.0f)) { self.currentPage = MIN(self.currentPage + 1, itemsCount - 1); } // Update offset by using item size + spacing CGFloat updatedOffset = (self.itemSize.width + self.minimumInteritemSpacing) * self.currentPage; self.previousOffset = updatedOffset; return CGPointMake(updatedOffset, proposedContentOffset.y); }
编辑:感谢您指出这一点,忘了说您必须先禁用分页:
self.collectionView.pagingEnabled = NO;
更新:附加Swift 4.2版本
... collectionView.isPagingEnabled = false ... class YourCollectionLayoutSubclass: UICollectionViewFlowLayout { private var previousOffset: CGFloat = 0 private var currentPage: Int = 0 override func targetContentOffset(forProposedContentOffset proposedContentOffset: CGPoint, withScrollingVelocity velocity: CGPoint) -> CGPoint { guard let collectionView = collectionView else { return super.targetContentOffset(forProposedContentOffset: proposedContentOffset, withScrollingVelocity: velocity) } let itemsCount = collectionView.numberOfItems(inSection: 0) // Imitating paging behaviour // Check previous offset and scroll direction if previousOffset > collectionView.contentOffset.x && velocity.x < 0 { currentPage = max(currentPage - 1, 0) } else if previousOffset < collectionView.contentOffset.x && velocity.x > 0 { currentPage = min(currentPage + 1, itemsCount - 1) } // Update offset by using item size + spacing let updatedOffset = (itemSize.width + minimumInteritemSpacing) * CGFloat(currentPage) previousOffset = updatedOffset return CGPoint(x: updatedOffset, y: proposedContentOffset.y) } }
你可以使用代码
self.collectionView.scrollToItem(at: indexPath, at: .centeredHorizontally, animated: true)
这是@ dmitry-zhukov的Swift 3版本(非常感谢btw!)
class PagedCollectionLayout : UICollectionViewFlowLayout { var previousOffset : CGFloat = 0 var currentPage : CGFloat = 0 override func targetContentOffset(forProposedContentOffset proposedContentOffset: CGPoint, withScrollingVelocity velocity: CGPoint) -> CGPoint { let sup = super.targetContentOffset(forProposedContentOffset: proposedContentOffset, withScrollingVelocity: velocity) guard let validCollection = collectionView, let dataSource = validCollection.dataSource else { return sup } let itemsCount = dataSource.collectionView(validCollection, numberOfItemsInSection: 0) // Imitating paging behaviour // Check previous offset and scroll direction if (previousOffset > validCollection.contentOffset.x) && (velocity.x < 0) { currentPage = max(currentPage - 1, 0) } else if (previousOffset < validCollection.contentOffset.x) && (velocity.x > 0) { currentPage = min(currentPage + 1, CGFloat(itemsCount - 1)) } // Update offset by using item size + spacing let updatedOffset = ((itemSize.width + minimumInteritemSpacing) * currentPage) self.previousOffset = updatedOffset let updatedPoint = CGPoint(x: updatedOffset, y: proposedContentOffset.y) return updatedPoint } }