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

时间:2019-02-20 13:02:22

标签: ios uitableview uistackview reuseidentifier

我在列表中有三个元素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. if cell == nil之后检查dequeueReusableCell。如果为零,则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,然后我都不会添加它们。

1 个答案:

答案 0 :(得分:1)

由于单元已被重用,因此您在cellForRowAt中要做的第一件事是“重置”您的单元...换句话说,从堆栈视图中清除现有的子视图:

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 {
        $0.removeFromSuperview()
    }

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

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

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