删除行UITableView索引问题

时间:2017-04-29 07:00:07

标签: ios swift uitableview

我使用下面的代码删除了tableview中的一行。首先,我从数组中删除对象,然后使用以下代码从tableview中删除:

let i = IndexPath(item: rowNum, section: 0)
myArray.remove(at: rowNum)
myTableView.deleteRows(at: [i], with: UITableViewRowAnimation.left)

但是,如果我之后删除了另一行,则不会删除我想要删除的行。问题是,即使我删除了tableview中的第一项(例如索引0),单击新的第一行将返回索引1 ...这是错误的,并删除第二行。删除第一行后,顶部的新行的索引应为0。

我可以通过以下方式解决这个问题:

mTableView.reloadData()

但这似乎不对......我不应该再次重新加载所有数据。

我还能做什么?

编辑:我在tableviewcell中有一个自定义按钮我要按删除行 - 不要滑动。

11 个答案:

答案 0 :(得分:6)

<强>问题

您遇到的问题是您在按钮上设置的标记,当您删除行时按钮标记不会更改,因为它的所有单元格都没有重新加载。 我猜您在cellforRowIndexpath中设置标记,尝试将标记放在tableWillDisplayCell

按钮上

最好的方法是在下面。

<强>解决方案

您可以通过其他方式获取IndexPath

  

假设您的视图层次结构是

     

UITableViewCell-&GT; contentView - &gt;按钮

按钮点击方法

 if let cell = sender.superview?.superview as? UITableviewCell{
        let indexPath = myTableView.indexPath(for: cell)
    // Now delete the table cell
    myArray.remove(at: indexPath.row)
    myTableView.beginUpdates()
    myTableView.deleteRows(at: [indexPath], with: UITableViewRowAnimation.left)
    myTableView.endUpdates()
}

我希望这对你有用。

答案 1 :(得分:1)

我不确定你从哪里得到你的变种rowNum,但对我来说,这个问题看起来像我已经发生过类似的情况。

对我来说,问题是传递到单元格indexPath中的tableView: cellForRowAt indexPath:导致在删除单元格时不会更新此值。

换句话说,在删除的单元格的按钮之后排序的所有按钮必须将其索引移动-1,否则它们将删除第n + 1行。

row A index 0
row B index 1
row C index 2
row D index 3

删除B它发生

row A index 0
row C index 2
row D index 3

当C应该有索引1而D应该有索引2.在这种情况下,点击按钮删除C将导致D被删除,点击按钮删除D将导致崩溃。

我希望我足够清楚。

答案 2 :(得分:0)

试试这个!

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

        //1. remove data from model
        data.remove(at: indexPath.row)

        //2. remove row from view
        tableView.deleteRows(at: [indexPath as IndexPath], with: .fade)
    }
}

答案 3 :(得分:0)

在相应单元格中按下按钮时删除行的智能解决方案。

  • 在自定义单元格类中声明一个回调变量

    var callback : (()->())?
    
  • 在自定义单元格类中,实现IBAction并将按钮连接到该操作

    @IBAction func buttonPressed(_ sender : UIButton) {
       callback?()
    }
    
  • cellForRowAtIndexPath中指定包含删除单元格的代码的闭包

    cell.callback = {
        self.myArray.remove(at: indexPath.row)
        tableView.deleteRows(at: [indexPath], with: .left)
    }
    

答案 4 :(得分:0)

我认为您将rowNum变量存储在您的单元格中,并在cellForRow(at:)方法中设置。如果我认为对,那么这就是事情。

UITableView尽量做到至少工作。这意味着,在您删除单元格后,UITableView无法再次在其数据源上调用cellForRow(at:)方法,直到您调用reloadData()reloadRows(at:animation:)方法。

因此,当您删除第一个单元格时,其他单元格上的rowNum变量将无法更新,直到您尝试调用reloadData()并看到它正常工作。

我的建议是不要将rowNum变量保留在单元格中,而是通过UITableView上的indexPath(for:)方法询问UITableView任何单元格的索引路径。

答案 5 :(得分:0)

Use Apple's Code

表视图与更新块内部调用的重新加载方法的行为方式相同 - 在执行动画块之前,会针对行和节的索引进行重新加载。无论插入,删除和重新加载方法调用的顺序如何,都会发生此行为。

[tv beginUpdates];
[tv deleteRowsAtIndexPaths:deleteIndexPaths withRowAnimation:UITableViewRowAnimationFade];
[tv endUpdates];

答案 6 :(得分:0)

删除行后,重新加载特定行

let indexPath = IndexPath(item: rowNum, section: 0)
array.remove(at: rowNum)
tableView.beginUpdates()
myTableView.deleteRows(at: [i], with: UITableViewRowAnimation.automatic)
tableView.endUpdates()
self.tableView.reloadRows(at: [indexPath], with: .automatic)

答案 7 :(得分:0)

我在我的应用程序中使用以下代码:

public func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath){

    if editingStyle == UITableViewCellEditingStyle.delete
    {
        myArray.remove(at: indexPath.row)
        myArray2.remove(at: indexPath.row)
        // you would also save the new array here so that the next time you open the tableview viewController it shows the changes made.

        mytableview.reloadData()

    }
}

答案 8 :(得分:0)

我遇到了这个问题,但是以前的答案都没有对我有用。如果您在myTableView.reloadData()所在的同一块中运行myTableView.deleteRows(at:with:),则动画无法正确运行。

您可以运行myTableView.performBatchUpdates(updates:completion:),在其中删除更新处理程序中的行,然后在完成处理程序中重新加载数据。这样,删除动画将正确运行,索引行也将同步。

myTableView.performBatchUpdates({
    myTableView.deleteRows(at: [i], with: UITableViewRowAnimation.left)
}, completion: {finished in
    myTableView.reloadData()
})

答案 9 :(得分:-1)

如果要从自定义按钮操作中删除tableview行,除了tableview commit editingStyle delegate 或任何tableview委托方法,则必须调用tableview reloadData以使用更新的索引值进行填充。

答案 10 :(得分:-1)

必须在tableView.beginUpdates()tableView.endUpdates()之间调用插入或删除行的任何方法。所以你的代码必须是:

let i = IndexPath(item: rowNum, section: 0)
myArray.remove(at: rowNum)

tableView.beginUpdates()

myTableView.deleteRows(at: [i], with: UITableViewRowAnimation.left)

tableView.endUpdates()