【问题标题】:Scaling down the height of a UICollectionViewCell dynamically动态缩小 UICollectionViewCell 的高度
【发布时间】: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 时更改集合视图单元格的高度?

【问题讨论】:

    标签: swift uicollectionview uicollectionviewcell uicollectionviewdelegateflowlayout


    【解决方案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问题的答案可以更好地满足您的目的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-20
    • 2014-04-02
    相关资源
    最近更新 更多