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上了,可以直接拿来使用

开源代码地址

相关推荐
他们都不看好你,偏偏你最不争气6 小时前
AutoLayout与Masonry:简化iOS布局
ios
2501_916008899 小时前
iOS 抓包工具有哪些?全面盘点主流工具与功能对比分析
android·ios·小程序·https·uni-app·iphone·webview
2501_915921439 小时前
iOS混淆工具实战 视频流媒体类 App 的版权与播放安全保护
android·ios·小程序·https·uni-app·iphone·webview
XXYBMOOO11 小时前
Qt UDP 通信类详解与实现
开发语言·网络·c++·qt·网络协议·ui·udp
2501_9160088913 小时前
uni-app iOS 日志与崩溃分析全流程 多工具协作的实战指南
android·ios·小程序·https·uni-app·iphone·webview
2501_9159214315 小时前
iOS混淆工具实战 在线教育直播类 App 的课程与互动安全防护
android·安全·ios·小程序·uni-app·iphone·webview
摘星编程15 小时前
Cursor Pair Programming:在前端项目里用 AI 快速迭代 UI 组件
前端·人工智能·ui·typescript·前端开发·cursorai
Digitally16 小时前
没 iCloud, 如何数据从iPhone转移到iPhone
ios·iphone·icloud
安卓开发者16 小时前
鸿蒙Next的UI国际化与无障碍适老化实践:构建全球包容的数字世界
ui·华为·harmonyos
笑尘pyrotechnic16 小时前
push pop 和 present dismiss
macos·ui·ios·objective-c·cocoa