动态缩小 UICollectionViewCell 的高度

Posted

技术标签:

【中文标题】动态缩小 UICollectionViewCell 的高度【英文标题】:Scaling down the height of a UICollectionViewCell dynamically 【发布时间】:2021-03-22 17:33:01 【问题描述】:

我正在使用UICollectionViewDelegateFlowLayout 在我的收藏视图中显示动态高度的单元格。单元格的大小在sizeForItemAt中设置。

目标:每个集合视图单元格都有一个切换功能,应将动态计算的高度更改为 50%。这就是我遇到问题的地方。

sizeForItemAt 我得到动态高度。

var dynamicHeight = (header + content + footer)
return CGSize(width: self.view.frame.width, height: dynamicHeight)

当单元格上的按钮被按下时,我想将sizeForItemAt 更新为以下内容:

return CGSize(width: self.view.frame.width, height: (dynamicHeight / 2))

如何在更新sizeForItemAt 时更改集合视图单元格的高度?

【问题讨论】:

【参考方案1】:

为了实现你想要的,你需要:

将单元格的状态存储在数据源中,以便collectionView(_:layout:sizeForItemAt:) 函数可以使用索引路径轻松访问它并 更改单元格的存储状态后,您需要调用集合视图的reloadItems(at:) 函数,传递单元格的索引路径,以更新单元格的大小。

您可以在以下代码中看到一个示例:

class TestCollectionViewCell: UICollectionViewCell 
    @IBOutlet weak var `switch`: UISwitch!
    var action: ((Bool) -> Void)?
    
    @IBAction func switchValueChanged(_ sender: UISwitch) 
        action?(sender.isOn)
    


private let reuseIdentifier = "Cell"

class TestCollectionViewController: UICollectionViewController, UICollectionViewDelegateFlowLayout 
    struct Item 
        let color: UIColor
        var scaledDown: Bool
    

    var items: [Item] = [
        .init(color: .red, scaledDown: false),
        .init(color: .green, scaledDown: false),
        .init(color: .black, scaledDown: false),
        .init(color: .orange, scaledDown: false),
        .init(color: .yellow, scaledDown: false),
        .init(color: .gray, scaledDown: false),
        .init(color: .darkGray, scaledDown: false),
        .init(color: .lightGray, scaledDown: false),
    ]

    // MARK: UICollectionViewDataSource

    override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int 
        return items.count
    

    override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell 
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifier, for: indexPath) as! TestCollectionViewCell
        let item = items[indexPath.item]
        
        cell.switch.isOn = item.scaledDown
        cell.backgroundColor = item.color
        cell.action =  [weak self] (isOn: Bool) in
            guard let self = self else  return 
            self.items[indexPath.item].scaledDown = isOn
            collectionView.reloadItems(at: [indexPath])
        
    
        return cell
    
    
    // MARK: - UICollectionViewDelegateFlowLayout
    
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize 
        let dynamicHeight: CGFloat = 200
        if items[indexPath.item].scaledDown 
            return CGSize(width: view.frame.width, height: (dynamicHeight / 2))
        
        return CGSize(width: view.frame.width, height: dynamicHeight)
    

【讨论】:

非常感谢!存储单元的状态绝对是我正在寻找的缺失部分。我意识到这有点超出范围,但是否可以在此处设置单元格大小变化的动画? @Joe 这实际上执行了UICollectionView 的默认动画。如果将collectionView.reloadItems(at: [indexPath]) 行放在UIView.performWithoutAnimation ... 块内,您可以看到区别。也许this问题的答案可以更好地满足您的目的。

以上是关于动态缩小 UICollectionViewCell 的高度的主要内容,如果未能解决你的问题,请参考以下文章

动态设置 UICollectionViewCell 的大小

UICollectionViewCell 中的动态高度 noScrollable UICollectionView

动态调整 UICollectionViewCell 的大小

使用图像上传 Swift 动态调整 UICollectionViewCell 的大小

具有动态大小单元格间距问题的 UICollectionViewCell

iOS - UICollectionViewCell 的动态大小宽度