UICollectionView动态自定义布局

时间:2015-04-28 21:23:48

标签: ios swift layout uicollectionview

我正在尝试使用布局类型创建一个UICollectionView作为我附加的图像。我对如何实现这种布局感到有点困惑。

在做了一些谷歌搜索后,似乎我需要编写一个自定义的UICollectionViewFlowLayout,但我似乎无法找到每个项目具有不同节数的布局示例。

如果您查看模型,则第一个项目有一个部分。图像为横向,但中间项目有2个部分,包含2个肖像图像。

我看错了吗?有人能指出我正确的方向吗?

Layout Mockup

2 个答案:

答案 0 :(得分:0)

您可以使用UICollectionViewDelegateFlowLayout执行此操作,无需子类化。

以下是一个例子:

import UIKit

class ViewController: UIViewController, UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout {

    @IBOutlet weak var collectionView: UICollectionView!

    override func viewDidLoad() {
        super.viewDidLoad()
        collectionView.delegate = self
        collectionView.dataSource = self
    }

    // MARK: - UICollectionViewDataSource

    func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int {
        return 1
    }

    func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return 10
    }

    func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCellWithReuseIdentifier("TestCollectionViewCell", forIndexPath: indexPath) as! UICollectionViewCell
        if indexPath.item % 3 == 0 {
            cell.backgroundColor = UIColor.redColor()
        } else {
            cell.backgroundColor = UIColor.greenColor()
        }
        return cell
    }

    // MARK: - UICollectionViewDelegateFlowLayout

    func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize {
        let flowLayout = collectionViewLayout as! UICollectionViewFlowLayout
        if indexPath.item % 3 == 0 {
            let cellWidth = (CGRectGetWidth(collectionView.frame) - (flowLayout.sectionInset.left + flowLayout.sectionInset.right))
            return CGSize(width: cellWidth, height: cellWidth / 2)
        } else {
            let cellWidth = (CGRectGetWidth(collectionView.frame) - (flowLayout.sectionInset.left + flowLayout.sectionInset.right) - flowLayout.minimumInteritemSpacing) / 2
            return CGSize(width: cellWidth, height: cellWidth)
        }
    }

}

答案 1 :(得分:0)

我喜欢Jacob Howcroft的回答,我发现可以改进UICollectionViewDelegateFlowLayout方法:

func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize {

    let flowLayout = collectionViewLayout as! UICollectionViewFlowLayout

    var numberOfCellsPerLine = 0

    if indexPath.item % 3 == 0 {
      numberOfCellsPerLine = 1
    } else {
      numberOfCellsPerLine = 2
    }

    // Generic cell width calculation 
    let cellWidth = (collectionView.bounds.width - (flowLayout.sectionInset.left + flowLayout.sectionInset.right)
        - flowLayout.minimumInteritemSpacing * CGFloat(numberOfCellsPerLine - 1)) / CGFloat(numberOfCellsPerLine)
    return CGSize(width: cellWidth, height: 100)

}

根据indexPath的不同,每行所需的单元数会更加明显(根据您的要求,您可以使用“if / else”或开关)。

此外,它使此代码具有超级可重用性,因为您始终必须考虑相同的元素(section inset,minimumInterItemSpacing)。