简介
大家都知道UICollectionView是带有自己的分页效果的,也就是pagingEnabled属性,可以实现整个屏幕滚动的效果,但是有场景就需要我们自己去分页效果了,例如以下效果
需求与思路
实现下图效果,每一次滑动cell都会完成的停留在红线方框之内
1.首先初始化一个UICollectionView,并且遵守UICollectionViewDataSource,UICollectionViewDelegate,UICollectionViewDelegateFlowLayout代理方法
2.实现父类UIScrollView的代理方法 scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer)
3.定义一个分页序号,通过通过selectedIndex的值,将要停下来的坐标y,计算位移,并且判断当位移绝对值大于分页宽度的一半时,滚动到位移方向的相邻页
4.在最后增加一个cell,防止滚动到最后一页出问题
5.根据滚动速度来停止
直接上代码
//第一
func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer) {
let y = targetContentOffset.pointee.y
let pageHeight = itemHeight
//通过selectedIndex的值,将要停下来的坐标y,计算位移
let moveindex = y - pageHeight*CGFloat(selectedIndex)
//当位移绝对值大于分页宽度的一半时,滚动到位移方向的相邻页
if moveindex < -pageHeight*0.5{
selectedIndex -= 1
}else if moveindex > pageHeight*0.5 {
selectedIndex += 1
}
if abs(velocity.y) >= 2{
targetContentOffset.pointee.y = pageHeight * CGFloat(selectedIndex)
}else{
targetContentOffset.pointee.y = scrollView.contentOffset.y
scrollView .setContentOffset(CGPoint(x: 0, y: pageHeight * CGFloat(selectedIndex)), animated: true)
}
}
//第二
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
switch indexPath.item {
case numberOfItem:
let n = UIScreen.main.bounds.size.height/itemHeight
let height = UIScreen.main.bounds.size.height - itemHeight*n
return CGSize(width: itemWith, height: height)
default:
return CGSize(width: itemWith, height: itemHeight)
}
}
最后<代码思路,如有相同之处,不是故意为之>附上demo地址 demo