iOS自定义collection view的page size(width/height)分页效果

前言

想必大家工作中或多或少会遇到下图样式的UI需求吧

像这种cell长度不固定,并且还能实现的分页效果UI还是很常见的

实现

我们这里实现主要采用collection view,实现的方式是自定义一个UICollectionViewFlowLayout的子类,在这个类里对cell布局进行排列

  • 当出现page size小于collection view的size的时候,可以使用ZLCollectionFreePageLayout一下子就实现分页效果
  • 并且不需要设置属性collectionView.isPagingEnabled = true ,只要设置了layout为ZLCollectionFreePageLayout,就可以自动实现这种效果

主要代码如下:

swift 复制代码
open override func targetContentOffset(forProposedContentOffset proposedContentOffset: CGPoint, withScrollingVelocity velocity: CGPoint) -> CGPoint {
        guard let collectionView = collectionView else {
            return super.targetContentOffset(forProposedContentOffset: proposedContentOffset, withScrollingVelocity: velocity)
        }
        
        var pWOrH: CGFloat = 0
        var contentOffsetXOrY: CGFloat = 0
        var collectionViewContentWOrH: CGFloat = 0
        var velocityXOrY: CGFloat = 0
        
        if scrollDirection == .horizontal {
            pWOrH = (pageWOrH == 0 ? collectionView.frame.width : pageWOrH) + minimumLineSpacing
            contentOffsetXOrY = collectionView.contentOffset.x
            collectionViewContentWOrH = collectionViewContentSize.width
            velocityXOrY = velocity.x
        } else {
            pWOrH = (pageWOrH == 0 ? collectionView.frame.height : pageWOrH) + minimumInteritemSpacing
            contentOffsetXOrY = collectionView.contentOffset.y
            collectionViewContentWOrH = collectionViewContentSize.height
            velocityXOrY = velocity.y
        }
        
        let originalPage = contentOffsetXOrY / pWOrH
        var nextPage = (velocityXOrY > 0) ? ceil(originalPage) : floor(originalPage)
        if (nextPage + 1.0) * pWOrH > collectionViewContentWOrH { nextPage -= 1.0 }
        
        let currentPage = (velocityXOrY > 0) ? floor(originalPage) : ceil(originalPage)
        let pannedLessThanOnePage = abs(1 + currentPage - originalPage) > 0.5
        let flicked = abs(velocityXOrY) > 0.01
        
        var newProposedContentOffset = proposedContentOffset
        if !(pannedLessThanOnePage && flicked) {
            nextPage = round(originalPage)
        }
        
        newProposedContentOffset.x = nextPage * pWOrH
        
        return newProposedContentOffset
    }
  • 在使用的时候,只需要将collection.collectionViewLayout的属性设置为我们自定义的layout对象,具体代码如下面的示例代码:
swift 复制代码
private lazy var collectionView: UICollectionView = {
  // 实例化一个ZLCollectionLeftLayout对象
  let defaultLayout = ZLCollectionFreePageLayout()
  
  // 自定义page width或者page height
  defaultLayout.pageWOrH = 200.0
  defaultLayout.minimumLineSpacing = 10.0
  defaultLayout.minimumInteritemSpacing = 10.0
  defaultLayout.scrollDirection = .vertical
  defaultLayout.sectionInset = UIEdgeInsets(top: 10.0, left: 10.0, bottom: 10.0, right: 10.0)
  // 设置collection view的layout为ZLCollectionFreePageLayout
  let collectionView = UICollectionView(frame: .zero, collectionViewLayout: defaultLayout)
  collectionView.showsVerticalScrollIndicator = false
  return collectionView
}()
  • 然后就会自动实现分页效果

  • 并且不需要 设置属性collectionView.isPagingEnabled = true

开源代码地址

代码开源到github上了,可以直接拿来使用

开源代码地址

相关推荐
清晨細雨8 小时前
UniApp集成极光推送详细教程
android·ios·uni-app·极光推送
余多多_zZ8 小时前
鸿蒙学习手册(HarmonyOSNext_API16)_应用开发UI设计:Swiper
学习·ui·华为·harmonyos·鸿蒙系统
长流小哥10 小时前
可视化开发:用Qt实现Excel级动态柱状图
开发语言·c++·qt·ui
ii_best12 小时前
iOS 按键越狱脚本支持一键新机软件教程
ios
lilili啊啊啊14 小时前
查看iphone手机的使用记录-克魔实战
ios·智能手机·iphone
鸿蒙布道师15 小时前
鸿蒙NEXT开发随机工具类(ArkTs)
android·ios·华为·harmonyos·arkts·鸿蒙系统·huawei
鸿蒙布道师1 天前
鸿蒙NEXT开发Base64工具类(ArkTs)
android·ios·华为·harmonyos·arkts·鸿蒙系统·huawei
美狐美颜sdk1 天前
美颜SDK兼容性挑战:如何让美颜滤镜API适配iOS与安卓?
android·深度学习·ios·美颜sdk·第三方美颜sdk·视频美颜sdk
小橙子20771 天前
一条命令配置移动端(Android / iOS)自动化环境
android·ios·自动化