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

Posted

技术标签:

【中文标题】使用自定义集合视图布局快速配置动态单元格高度【英文标题】:Configuring dynamic cell height with a custom collection view layout swift 【发布时间】:2018-09-09 23:40:32 【问题描述】:

我有一个自定义集合视图布局,它从下到上为消息传递应用程序加载单元格,但在实现动态单元格高度时遇到问题。我相信我为检索动态单元格高度而连接的协议和委托对每个单元格都有效(我从打印每个 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】:

使用此方法更改高度,UICollectionViewCell。

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize 
    return CGSize(width: 125.0, height: 175.0)

【讨论】:

它没有用。我的准备函数检索到正确的高度,但我在将执行它的类的主体中找不到这段代码。它们都执行一个静态高度,即第一个单元格的高度。

以上是关于使用自定义集合视图布局快速配置动态单元格高度的主要内容,如果未能解决你的问题,请参考以下文章

根据图像高度在集合视图自定义布局中获取单元格的高度

如何使用故事板中定义的单元格计算集合视图单元格高度?

多个自定义视图的自动布局问题

如何根据标签文本快速更改表格视图单元格高度?

如何根据其中的内容创建具有动态高度的集合视图?

使自定义单元格(使用自动布局创建)高度为零