效果展示
分析
如果直接打开系统的pagingEnabled
分页, 它只会根据Cell的Bounds分页。如果cell不是屏幕宽度的话,就不能使用了,需要我们对滚动进行计算了。
方案一
- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset { *targetContentOffset = scrollView.contentOffset; float pageWidth = (float)self.articlesCollectionView.bounds.size.width; int minSpace = 10;
int cellToSwipe = (scrollView.contentOffset.x)/(pageWidth + minSpace) + 0.5; if (cellToSwipe < 0) { cellToSwipe = 0; } else if (cellToSwipe >= self.articles.count) { cellToSwipe = self.articles.count - 1; } [self.articlesCollectionView scrollToItemAtIndexPath:[NSIndexPath indexPathForRow:cellToSwipe inSection:0] atScrollPosition:UICollectionViewScrollPositionLeft animated:YES]; }
|
在手指松开的时候,开始计算滚动的下一个位置。这个方法虽然也可以实现需求,但是效果比较生硬,不是很推荐。
具体可以看 :查看其中的「分页的几种实现方式」
方案二
- (CGPoint)targetContentOffsetForProposedContentOffset:(CGPoint)offset withScrollingVelocity:(CGPoint)velocity {
CGRect cvBounds = self.collectionView.bounds; CGFloat halfWidth = cvBounds.size.width * 0.5f; CGFloat proposedContentOffsetCenterX = offset.x + halfWidth;
NSArray* attributesArray = [self layoutAttributesForElementsInRect:cvBounds];
UICollectionViewLayoutAttributes* candidateAttributes; for (UICollectionViewLayoutAttributes* attributes in attributesArray) {
if (attributes.representedElementCategory != UICollectionElementCategoryCell) { continue; }
if(!candidateAttributes) { candidateAttributes = attributes; continue; }
if (fabs(attributes.center.x - proposedContentOffsetCenterX) < fabs(candidateAttributes.center.x - proposedContentOffsetCenterX)) { candidateAttributes = attributes; } }
return CGPointMake(candidateAttributes.center.x - halfWidth, offset.y);
}
|
通过重写UICollectionViewLayout的方法,根据计算返回最终的悬停位置。
目前还存在的问题
滑动如果比较慢的话,它跳转到下一页的也会比较慢。
可以通过设置 decelerationRate
的值,来决定手指放开后的减速率,范围为0-1。然而经过测试,发现是可以加速,但是会出现莫名的卡顿。
2017年3月10号更新
使用UIScrollview
按照view
宽度分页的方法:
详见DEMO: https://github.com/labmain/UIScrollViewCellWidthPage
解决了 UICollectionView
滑动比较慢的问题。
Demo 地址
github