Добавьте UIViews к UIStackView программно внутри UITableView

У меня есть три элемента UILabel, UIImageView а также UIButton в списке. Я должен показать их соответственно внутри 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 ответ

Решение

Поскольку клетки используются повторно, первое, что вам нужно сделать в 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
    ...
}

Теперь, основываясь на представленном вами коде, если ячейки всегда содержат UILabel, UIImageView а также UIButtonпросто в разных порядках и с разными свойствами, вы можете добавить их один раз при создании ячейки (или добавить их в прототип ячейки, если вы ее используете), а затем просто переупорядочить их по мере необходимости.

Другие вопросы по тегам