UICollectionview进阶:自定义布局(-)

流式布局:不规则的瀑布流,主要通过继承UICollectionViewFlowLayout,自定义布局。

UICollectionViewFlowLayout

  1. prepareLayout()
  2. collectionViewContentSize()
  3. layoutAttributesForElementsInRect(_:)
  4. layoutAttributesForItem(at indexPath: IndexPath)

这几个方法或者属性是需要重写。从后往前详细了解这几个方法。其实是有一定的逻辑流程的。

流程

  1. 首先需要确定在indexPath位置的item的frame
  2. 其次告诉在区域范围内,显示所有item的布局信息。
  3. 告诉UIcollectionview滚动的区域范围
  4. 提前计算,所需要的布局属性.

可以逆向思维整个流程。先确定一个item的布局信息,然后所有item组成了区域内的布局,返回整个布局滚动的范围。

    //内容宽度
    let contentWidth = screenWidth
    //内容高度
    var contentHeight: CGFloat = 0
    //列数
    let numberOfColumns = 2
    //存储布局属性数组,提高性能
    var cache = [UICollectionViewLayoutAttributes]()
    
复制代码
 override func layoutAttributesForItem(at indexPath: IndexPath) -> UICollectionViewLayoutAttributes? {
       //返回在具体item的位置信息。
        return cache[indexPath.row]
    }
复制代码
override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
        //返回在区域范围内,所有的布局信息
        return cache
    }
复制代码
override var collectionViewContentSize: CGSize {
        //整个显示布局的区域
        return CGSize(width: contentWidth, height: contentHeight)
    }
复制代码
override func prepare() {
        super.prepare()
        //准备显示布局时候,提前计算item的布局属性,内容区域,并进行缓存。提高性能。
         if cache.isEmpty {
            // 2. Pre-Calculates the X Offset for every column and adds an array to increment the currently max Y Offset for each column
            // 每列宽度
            let columnWidth = contentWidth / CGFloat(numberOfColumns)
            var xOffset = [CGFloat]()
            // 其实就是xOffset就是两个,都是固定的.
            for column in 0 ..< numberOfColumns {
                xOffset.append(CGFloat(column) * columnWidth )
            }
            var column: Int = 0
            var yOffset = [CGFloat](repeating: 0, count: numberOfColumns)
            // 3. Iterates through the list of items in the first section
            for item in 0 ..< collectionView!.numberOfItems(inSection: 0) {
                let indexPath = NSIndexPath(item: item, section: 0)
                // 4. Asks the delegate for the height of the picture and the annotation and calculates the cell frame.
                // 这个width是为了计算comment的长度的.
                let randomNumber:Int = Int(arc4random() % 100) + 60
                let height = CGFloat(randomNumber)
                let frame = CGRect(x: xOffset[column], y: yOffset[column], width: columnWidth, height: height)
                // 5. Creates an UICollectionViewLayoutItem with the frame and add it to the cache
                let attributes = UICollectionViewLayoutAttributes.init(forCellWith: indexPath as IndexPath)
                attributes.frame = frame
                cache.append(attributes)
                // 6. Updates the collection view content height
                contentHeight = max(contentHeight, frame.maxY)
                yOffset[column] = yOffset[column] + height
                column = column >= (numberOfColumns - 1) ? 0 : 1
            }
        }
}
复制代码

总结

核心是计算item所在位置的布局信息。
prepare()去缓存,提高性能。

引用 叶孤城:UICollectionView自定义布局教程——Pinterest - CocoaChina_让移动开发更简单
iOS开发进阶 - 自定义UICollectionViewLayout实现瀑布流布局 - W_C__L的博客 - CSDN博客

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值