首页 > 解决方案 > 如何在 UITableView 中正确移动和删除行?

问题描述

在我的用例中,单元格被移动到 indexPath 0-0,然后从数组中删除。这两个动作都包含在beginUpdates() endUpdates(). 这导致willDisplay和问题didEndDisplaying
有时didEndDisplaying甚至没有调用或willDisplay调用两次或更多次,这使我的单元格被多次限制。

这是示例项目:https ://github.com/mNijurin/table_playground 该项目在单元格的标签
上添加“1”willDisplay并将其删除。didEndDisplaying所以在任何情况下,我们都必须看到空字符串或多个“11”之类的东西。

当点击“do”按钮时,程序会将第 50 行移动到 indexPath 0-0 并将其删除。

滚动到 50 行并点击“执行”屏幕上的所有单元格将被限制两次。我们可以用显示“11”的标签来检查它

这是视频:https ://youtu.be/nCWkk2eLDWc

这是代码:

var texts = [String]()    

override func viewDidLoad() {
    super.viewDidLoad()
    navigationItem.rightBarButtonItem = UIBarButtonItem(title: "do", style: .plain, target: self, action: #selector(doSome))

    navigationController?.navigationBar.isOpaque = true
    for i in 0...100 {
        texts.append("\(i)")
    }
}

@objc func doSome() {
    let text = texts[50]
    texts.remove(at: 50)
    texts.insert(text, at: 0)
    tableView.beginUpdates()
    tableView.moveRow(at: IndexPath(row: 50, section: 0), to: IndexPath(row: 0, section: 0))
    tableView.endUpdates()

    texts.remove(at: 0)
    tableView.beginUpdates()
    tableView.deleteRows(at: [IndexPath(row: 0, section: 0)], with: .bottom)
    tableView.endUpdates()
}

override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return texts.count
}

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    if let someCell = tableView.dequeueReusableCell(withIdentifier: "cell") {
        return someCell
    } else {
        let cell = UITableViewCell(style: .default, reuseIdentifier: "cell")
        let label = UILabel(frame: CGRect(x: 50, y: 0, width: 300, height: 40))
        label.textColor = .black
        label.tag = 13
        cell.textLabel?.addSubview(label)
        return cell
    }
}

override func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
    print("bind row: \(indexPath.row) \(Unmanaged.passUnretained(cell).toOpaque())")
    cell.textLabel?.text = texts[indexPath.row]

    let label = cell.contentView.viewWithTag(13) as? UILabel
    label?.text = "\(label?.text ?? "")1"
    print("willDisplay \(label?.text ?? "")")
}

override func tableView(_ tableView: UITableView, didEndDisplaying cell: UITableViewCell, forRowAt indexPath: IndexPath) {
    print("unbind row: \(indexPath.row) \(Unmanaged.passUnretained(cell).toOpaque())")
    cell.textLabel?.text = nil

    let label = cell.contentView.viewWithTag(13) as? UILabel
    if let text = label?.text, text.count == 1 {
        label?.text = ""
    } else if let text = label?.text, text.count > 0 {
        var text = text
        text.remove(at: text.index(text.endIndex, offsetBy: -1))
        label?.text = text
    }
    print("endDisplay \(label?.text ?? "")")
}

`

标签: iosiphoneswift

解决方案


从 tableview 中删除行

yourTableView.beginUpdates()
yourTableView.deleteRows(at: [IndexPath(row: yourModelArray.count - 1, section: 0)], with: .automatic)
yourTableView.endUpdates()

推荐阅读