使用自定义集合视图布局快速配置动态单元格高度

时间:2018-09-09 23:40:32

标签: ios swift uicollectionview

我有一个自定义的集合视图布局,该布局从下至上为消息传递应用程序加载了单元格,但我在实现动态单元格高度时遇到了麻烦。我相信我挂接来检索动态单元格高度的协议和代表对于每个单元格都有效(这是我从打印每个indexPath.item的高度得出的),除非在加载collectionView时,单元格的高度不是它们的高度应该是。它们都是一个静态高度(不是var cellHeight预设的80),并且只显示一行文本。

 protocol InvertedStackProtocol: class {
    func collectionView(_ collectionView: UICollectionView, heightForCellAtIndexPath indexPath: IndexPath) -> CGFloat
    }

    class InvertedStackLayout: UICollectionViewLayout, UICollectionViewDelegateFlowLayout {

    var cellHeight: CGFloat = 80

    weak var delegate: InvertedStackProtocol!

    override func prepare() {

        guard let collectionView = self.collectionView else {return}

        for item in 0 ..< collectionView.numberOfItems(inSection: 0) {
            let indexPath = IndexPath(item: item, section: 0)
            let height = delegate.collectionView(collectionView, heightForCellAtIndexPath: indexPath)
            print (height, indexPath.item)
            cellHeight = height
        }

    }

    override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
        var layoutAttrs = [UICollectionViewLayoutAttributes]()

        if let collectionView = self.collectionView {
            for section in 0 ..< collectionView.numberOfSections {
                if let numberOfSectionItems = numberOfItemsInSection(section) {
                    for item in 0 ..< numberOfSectionItems {
                        let indexPath = IndexPath(item: item, section: section)
                        let layoutAttr = layoutAttributesForItem(at: indexPath)

                        if let layoutAttr = layoutAttr, layoutAttr.frame.intersects(rect) {
                            layoutAttrs.append(layoutAttr)
                        }
                    }
                }
            }
        }

        return layoutAttrs
    }

    override func layoutAttributesForItem(at indexPath: IndexPath) -> UICollectionViewLayoutAttributes? {
        let layoutAttr = UICollectionViewLayoutAttributes(forCellWith: indexPath)
        let contentSize = self.collectionViewContentSize

        layoutAttr.frame = CGRect(
            x: 0, y: contentSize.height - CGFloat(indexPath.item + 1) * cellHeight,
            width: contentSize.width, height: cellHeight)

        return layoutAttr
    }

    func numberOfItemsInSection(_ section: Int) -> Int? {
        if let collectionView = self.collectionView,
            let numSectionItems = collectionView.dataSource?.collectionView(collectionView, numberOfItemsInSection: section)
        {
            return numSectionItems
        }

        return 0
    }

    override var collectionViewContentSize: CGSize {
        get {
            var height: CGFloat = 0.0
            var bounds = CGRect.zero

            if let collectionView = self.collectionView {
                for section in 0 ..< collectionView.numberOfSections {
                    if let numItems = numberOfItemsInSection(section) {
                        height += CGFloat(numItems) * cellHeight
                    }
                }

                bounds = collectionView.bounds
            }

            return CGSize(width: bounds.width, height: max(height, bounds.height))
            // return CGSize(width: bounds.width, height: height) do this for more exact fit of collection view
        }
    }

    override func shouldInvalidateLayout(forBoundsChange newBounds: CGRect) -> Bool {
        if let oldBounds = self.collectionView?.bounds,
            oldBounds.width != newBounds.width || oldBounds.height != newBounds.height
        {
            return true
        }

        return false
    }
}

1 个答案:

答案 0 :(得分:0)

使用此方法更改高度UICollectionViewCell。

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
    return CGSize(width: 125.0, height: 175.0)
}
相关问题