在 UITableView 中以编程方式将 UIViews 添加到 UIStackView

Add UIViews to UIStackView programmatically inside UITableView

我在列表中有三个元素 UILabelUIImageViewUIButton。我必须在 UITableView 中相应地显示它们。我有一个这样的数组:

tableArray = [["label", "img", "button"],["img","button","label"],["img","label","button"],["button", "img", "label"]]

元素的位置与它们(索引)在数组中的位置相同。我的 cellForRowAt 看起来像这样:

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    guard let cell = tableView.dequeueReusableCell(withIdentifier: "FirstTableViewCell", for: indexPath) as? FirstTableViewCell else {
        return UITableViewCell()
    }

    let tableData = tableArray[indexPath.row]

    var count = 0
    tableData.forEach { (element) in
        switch element {
        case "label":
            let lbl = self.createLabel()

            cell.stackView.insertArrangedSubview(lbl, at: count)
            count += 1
            break
        case "img":
            let img = self.createImage()
            cell.stackView.insertArrangedSubview(img, at: count)
            count += 1
            break
        case "button":
            let btn = self.createButton()
            cell.stackView.insertArrangedSubview(btn, at: count)
            count += 1
            break
        default:
            break
        }
    }
    return cell
}

问题是每当我滚动 TableView 每次将这些项目添加到单元格中时。

我尝试了一些解决方案来解决这个问题,但没有成功。

  1. if tableView.cellForRow(at: indexPath) == nil 然后将元素添加到堆栈视图中。

  2. dequeueReusableCell 之后检查 if cell == nil。如果为零则 init 单元格。

  3. let cell = UITableViewCell.init(style: .default, reuseIdentifier: nil) as? FirstTableViewCell 即使没有 dequeueReusableCell 也尝试过。

但每次都发生同样的事情。

这是FirstTableViewCell

class FirstTableViewCell: UITableViewCell {

    @IBOutlet weak var stackView: UIStackView!

    override func awakeFromNib() {
        super.awakeFromNib()
        // Initialization code
    }

    override func setSelected(_ selected: Bool, animated: Bool) {
        super.setSelected(selected, animated: animated)

        // Configure the view for the selected state
    }
}

知道如何检查元素是否已添加到 StackView,那么我不会添加它们。

因为单元格被重复使用,所以您在 cellForRowAt 中需要做的第一件事是 "reset" 您的单元格...换句话说,从堆栈视图中清除现有的子视图:

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    guard let cell = tableView.dequeueReusableCell(withIdentifier: "FirstTableViewCell", for: indexPath) as? FirstTableViewCell else {
        return UITableViewCell()
    }

    // remove the views that are currently in the stack
    cell.stackView.arrangedSubviews.forEach {
        [=10=].removeFromSuperview()
    }

    // the rest of your setup
    let tableData = tableArray[indexPath.row]

    var count = 0
    tableData.forEach { (element) in
    ...
}

现在,根据您提供的代码,如果单元格始终包含 UILabelUIImageViewUIButton,只是顺序不同且属性不同,您可以添加在您创建单元格时将它们添加一次(或者如果您正在使用它们,则将它们添加到您的单元格原型中),然后根据需要简单地重新排列它们。