从UITableView

时间:2017-06-19 16:32:55

标签: ios swift uitableview delete-row

请帮我找出我的错误。我有一个表视图,数据源是一个名为items的数组。从items数组中删除一个项后,调用的cellForRowAt方法和参数indexPath.row等于items.count。仅当行数足以使一个项目超出表视图的视图时,才会发生这种情况。 当它发生时会导致致命错误(索引超出范围)。在这种情况下使用hack并降低IndexPath.row的值。

请参阅以下图片:

enter image description here

以下为cellForRowAt的代码:

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
{
    let cell = tableView.dequeueReusableCell(withIdentifier: "ItemCell", for: indexPath) as! ItemCell

    var i = indexPath.row
    if i >= items.count { i = items.count - 1 } //XXX: hack! Sometimes called with indexPath.row is equal with items.count :(
    cell.set(items[i])

    return cell
}

以下代码为删除:

    func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath)
{
    if (editingStyle == UITableViewCellEditingStyle.delete)
    {
        items.remove(at: indexPath.row)

        tableView.deleteRows(at: [indexPath], with: UITableViewRowAnimation.fade)
    }
}

我认为不相关,但我使用的是iOS 11.0

更新

我试过,以下非常简单的代码也会受到影响:

    class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate
{
    var items = ["0","1","2","3","4","5","6","7","8","9","A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z"]

    override func viewDidLoad()
    {
        super.viewDidLoad()
    }

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

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
    {
        let cell = tableView.dequeueReusableCell(withIdentifier: "ItemCell", for: indexPath)
        cell.textLabel?.text = "\(items[indexPath.row])"

        return cell
    }

    func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath)
    {
        if (editingStyle == UITableViewCellEditingStyle.delete)
        {
            items.remove(at: indexPath.row)
            tableView.deleteRows(at: [indexPath], with: UITableViewRowAnimation.fade)
        }
    }
}

如何重现:

  1. 向下滚动至Y是屏幕上的最后一项
  2. enter image description here

    1. 尝试删除Y向左滑动
    2. enter image description here

      1. 并收到以下错误
      2. enter image description here

        enter image description here

1 个答案:

答案 0 :(得分:3)

您的删除代码看起来不错,但您不应该在cellForRowAt中执行您正在执行的操作。这样做是这样的:

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "ItemCell", for: indexPath) as! ItemCell
    cell.set(items[indexPath.row])

    return cell
}

你的numberOfRowsInSection应该是这样的:

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

<强>更新
我们刚刚确认这是与Xcode 9 beta和iOS 11相关的错误。在Xcode 8.x上工作正常。 OP会就此向{Apple}提交bug