Collection view自定义布局
一般我们自定义布局都会新建一个类,继承自UICollectionViewFlowLayout,然后重写几个方法:
- prepareLayout():当准备开始布局时调用这个方法,可以在这里计算一些属性,比如cell的尺寸。
- layoutAttributesForElementsInRect(rect: CGRect) -> [UICollectionViewLayoutAttributes]?:在这里返回布局属性。
实例(比较简单的例子,实际开发中可以进行更多的封装)
第一步:声明两个属性
// MARK: 属性 /** cell的个数 */ var itemCount: Int? /** 布局信息 */ var layoutAttributes = [UICollectionViewLayoutAttributes]()
第二步:重写prepareLayout方法,计算布局属性
// MARK: 准备布局 override func prepareLayout() { super.prepareLayout() // 计算每个cell的宽度 let width = (UIScreen.mainScreen().bounds.size.width - self.sectionInset.left - self.sectionInset.right - minimumInteritemSpacing) / 2.0 // 判断itemCount是否为空 if itemCount != nil { // 开始计算每个cell的布局属性 calculationAttribute(withItemWidth: width) } }
func calculationAttribute(withItemWidth itemWidth: CGFloat) { // 声明数组 保存每一列的总高度 (两列) let column1 = sectionInset.top, column2 = sectionInset.top var columnArray: [CGFloat] = [column1, column2] for index in 0..<itemCount! { // 创建indexPath 因为是示例 所以排版固定在一组 let indexPath = NSIndexPath(forItem: index, inSection: 0) // 创建布局属性 通过indexPath let attribute = UICollectionViewLayoutAttributes(forCellWithIndexPath: indexPath) // 创建一个随机高度 let itemHeight = CGFloat(arc4random()%150 + 100) // columnNumber 记录定义的是哪一列 var columnNumber: CGFloat if columnArray[0] < columnArray[1] { columnArray[0] += itemHeight + self.minimumLineSpacing columnNumber = 0 } else { columnArray[1] += itemHeight + self.minimumLineSpacing columnNumber = 1 } // 设置item的位置 let x = self.sectionInset.left + (self.minimumLineSpacing + itemWidth) * columnNumber let y = columnArray[Int(columnNumber)] - itemHeight - self.minimumLineSpacing attribute.frame = CGRectMake(x, y, itemWidth, itemHeight) layoutAttributes.append(attribute) } // 当设置完所有item的位置后需要设置itemsize 这样才能保证滚动时能显示所有的cell // itemsize的height属性 是取最高的那列的平均值 if columnArray[0] > columnArray[1] { self.itemSize = CGSizeMake(itemWidth, (columnArray[0] - sectionInset.top) * 2 / CGFloat(itemCount!) - self.minimumLineSpacing) } else { self.itemSize = CGSizeMake(itemWidth, (columnArray[1] - sectionInset.top) * 2 / CGFloat(itemCount!) - self.minimumLineSpacing) } }
第三步:返回布局信息数组
override func layoutAttributesForElementsInRect(rect: CGRect) -> [UICollectionViewLayoutAttributes]? { return layoutAttributes }
总结:这个例子是瀑布流的布局,如果需要别的布局需要在准备布局时计算,然后返回布局信息数组就可以了
时间: 2024-10-25 21:17:02