【问题标题】:UITableViewCell dynamic cell heights are incorrect until scrolledUITableViewCell 动态单元格高度在滚动之前不正确
【发布时间】:2021-09-26 16:55:45
【问题描述】:

我希望我的 UITableViewCell 在点击时扩大尺寸。

单元格的布局非常简单。在 UITableViewCell 中有一个 UILabel。 UILabel 被约束到具有顶部、底部、左侧和右侧锚点的 UITableViewCell。

我还有两个存储属性。 labelExpandedHeightConstraint 存储 UILabel 在标签展开时的高度约束。 labelCompactHeightConstraint 存储 UILabel 压缩标签时的高度约束。请注意,labelCompactHeightConstraint 最初设置为活动状态。

override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
        let spacing = 8

        self.addSubview(self.labelView)
                
        self.labelView.translatesAutoresizingMaskIntoConstraints = false

        self.labelView.topAnchor.constraint(equalTo: self.topAnchor, constant: spacing).isActive = true
        self.labelView.bottomAnchor.constraint(equalTo: self.bottomAnchor, constant: -1 * spacing).isActive = true
        self.labelView.leftAnchor.constraint(equalTo: self.leftAnchor, constant: spacing).isActive = true
        self.labelView.rightAnchor.constraint(equalTo: self.rightAnchor, constant: -1 * spacing).isActive = true
                
        self.labelExpandedHeightConstraint = self.labelView.heightAnchor.constraint(equalToConstant: 120)
        self.labelCompactHeightConstraint = self.labelView.heightAnchor.constraint(equalToConstant: 80)
        self.labelCompactHeightConstraint.isActive = true
}

只要用户点击UITapGestureRecognizer,就会调用下面的expand() 函数。这个功能非常简单。它通过禁用labelCompactHeightConstraint 并启用labelExpandedHeightConstraint 来扩展单元格。

@objc func expand() {
        self.labelCompactHeightConstraint.isActive = false
        self.labelExpandedHeightConstraint.isActive = true
        self.layoutIfNeeded()
    }

问题在于,当调用expand() 函数时,UITableViewCell 及其内容的大小不会改变。直到用户将单元格从屏幕上滚动出来,然后再将其滚动回屏幕上,尺寸才会正确调整。

如何让单元格在点击时立即展开?我也希望这个尺寸变化是动画的。我真的很感激任何建议。谢谢!

【问题讨论】:

标签: ios swift uitableview


【解决方案1】:

您需要采取不同的做法。
比如:

tableView.beginUpdates()
// update data for cell, or if your cell is not dynamically created - update it directly
// Usually, you'll need to update your data structures 
// Reload the cell
tableView.reloadRows(at: [indexPath], with: .automatic)
tableView.endUpdates()

根据你写的,添加这段代码的地方来自:

override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
...
}

另外,请注意,在大多数情况下,您应该只更改内容(即标签中的文本)而不是约束值。

这是一个最小的完整示例:

class ViewController: UITableViewController {
    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 100
    }
    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "ident", for: indexPath) as! Cell
        if selections.contains(indexPath) {
            cell.height.constant = 80
        } else {
            cell.height.constant = 10
        }
        return cell
    }
    override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        tableView.beginUpdates()
        if selections.contains(indexPath){
            selections.remove(indexPath)
        } else {
            selections.insert(indexPath)
        }
        tableView.reloadRows(at: [indexPath], with: .automatic)
        tableView.endUpdates()
    }
    var selections = Set<IndexPath>()
}

class Cell : UITableViewCell {
    @IBOutlet var height : NSLayoutConstraint!
}

可以使用表格视图的多项选择,但想演示应用特定数据的用法。

【讨论】:

    猜你喜欢
    • 2014-11-16
    • 1970-01-01
    • 1970-01-01
    • 2014-09-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-09
    • 2016-08-16
    相关资源
    最近更新 更多