前提: 要实现一个类似抖音发布视频选择音乐的UI,翻页的时候使用pagingEnabled 不能实现产品的需求。上网翻阅了一下资料,最终解决方案如下:
这一篇内容很多,我只关注了关于scrollView翻页的部分
https://tech.glowing.com/cn/practice-in-uiscrollview/
这个我觉得是可以解决的,但是我没太看懂要如何设置,试了一下没有成功
https://www.jianshu.com/p/db9d31aba2e8
这一篇我觉得实现的方式比较老,直接放弃了。
https://www.cnblogs.com/v-jing/p/3509219.html
这两篇我试了一下,确实scrollView的可以,但是CollectionView因为复用问题,设置clipsToBound = NO展示还是有问题。 如果用他说的另一种再加一个占位ScrollView的话,比较担心点击的问题,也放弃了这种实现方式
http://khanlou.com/2013/04/changing-the-size-of-a-paging-scroll-view/
http://khanlou.com/2013/04/paging-a-overflowing-collection-view/
https://blog.csdn.net/weixin_33849942/article/details/86872754
最后实现的是这种方式 https://www.jianshu.com/p/8adf8e696299
下面是我实现的效果
实际效果顺滑,这个图片传上来有点卡顿似的。
效果.gif
下面是我实现的过程:
注意 :需要设置CollectionView的一些属性
是否可以分页
collectionView.pagingEnabled = NO
设置滚动减速的效果
collectionView.decelerationRate = UIScrollViewDecelerationRateFast
- 全局设置两个属性值
// 手势开始时的起始页数
@property (assign, nonatomic) NSInteger pageOnBeginDragging;
// 总页数
@property (nonatomic, assign) NSInteger pageCount;
- 刷新的方法里面计算pagecount
- (void)reloadData {
[self.collectionView reloadData];
CGFloat collectionViewWidth = self.collectionView.contentSize.width - collectionViewListEdgeRight;
_pageCount = (collectionViewWidth > 0) ? ceil((double)collectionViewWidth / (double)itemSize_width()) : 0;
}
- 实现scrollView的代理方法
// 用户拖拽开始时记录状态,计算当前展示的页数
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
// collection 当前的偏移量
CGFloat offsetX = scrollView.contentOffset.x;
// 计算当前页码 = 偏移量 / 页的宽度
NSInteger i = ceil((double)offsetX/(double)pageWidth);
// 赋值到全局变量 后面需要使用
self.pageOnBeginDragging = i;
}
/*
这个代理方法在用户拖拽即将结束时被调用,velocity代表结束时scrollView滚动的速度
velocity > 0代表正在往contentOffset值增加的方向滚动,
velocity < 0滚动方向相反
targetContentOffset参数有inout修饰,可以通过修改改值决定最终scrollView滚动到的位置,一看就是用来判断/实现翻页的完美方法
*/
- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset {
// 每页宽度
CGFloat pageWidth = itemSize_width();
// 当前的偏移量
CGFloat targetX = (*targetContentOffset).x;
// 当前的页码数
NSInteger targetPage = self.pageOnBeginDragging;
// 综合考虑velocity和targetContentOffset这两方面因素决定targetpage
if (velocity.x == 0) {
// 没有移动的情况
targetPage = ceil((double)targetX/(double)itemSize_width());
} else {
// 正方向向右移动 && 不是最后一页的时候
if (velocity.x>0 && (targetPage+1<self.pageCount)) {
targetPage++;
}
// 反方向移动 && 不是第一页的时候 targetPage == 0(有数据就不存在)
if (velocity.x<0 && targetPage-1>=0) {
targetPage--;
}
}
// 设置targetContentOffset 要滚动的位置 页面宽度 * 页数
CGPoint offset = CGPointMake(pageWidth * targetPage, 0);
*targetContentOffset = offset;
}










网友评论