在 Swift 中从 UITableView 中删除一行?

Posted

技术标签:

【中文标题】在 Swift 中从 UITableView 中删除一行?【英文标题】:Deleting a Row from a UITableView in Swift? 【发布时间】:2017-03-02 13:30:05 【问题描述】:

我有一个名称表,我正在为它们创建一个滑动和删除函数,将它们从一个数组的名称变量中删除。

我选择了与 xcode 中的教程最相似的函数并填写了它们,但是当我单击删除按钮时,我的应用程序随机崩溃。这是我的删除按钮代码:

func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]? 
    let deleteAction = UITableViewRowAction(style: .destructive, title: "Delete")  (rowAction: UITableViewRowAction, indexPath: IndexPath) -> Void in
        print("Deleted")
        self.catNames.remove(at: indexPath.row)
        self.tableView.deleteRows(at: [indexPath], with: UITableViewRowAnimation.automatic)
        self.tableView.reloadData()
    

我是编码和学习 swift 的新手,我正在学习 swift 2 的教程并使用 swift 3,所以我在学习时遇到了一些问题,这是我正确坚持的问题。

【问题讨论】:

只需删除对reloadData的调用。 仅供参考 - 每当您发布有关崩溃的问题时,您必须包含有关崩溃的相关详细信息,包括导致崩溃的确切行和完整的错误消息。 删除reloadData 调用不会解决问题。看看下面的答案。 @PhilHudson 当 OP 已经正确调用 deleteRows 时,无需调用 reloadData。在 OP 发布有关崩溃的详细信息之前,无法确定完整的解决方案可能是什么。 @maddy 只看代码就知道bug在哪里了。当然它应该提供崩溃日志,但您建议的是最佳实践,而不是实际的根本原因。 【参考方案1】:

适用于 Swift 3Swift 4

使用 UITableViewDataSource tableView(:commit:forRowAt:) 方法,另见此答案here:

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

    self.catNames.remove(at: indexPath.row)
    self.tableView.deleteRows(at: [indexPath], with: .automatic)
  

【讨论】:

不,不要为了删除一行而调用reloadData。这是一种不好的做法。 你是对的@rmaddy!更新了答案并想将其链接到之前提到过的另一个答案,但不幸的是 on 删除了它 没有理由在对表格视图进行一次更改时使用begin/endUpdates @rmaddy 感谢您的信息 值得注意的是,这应该在主线程上调用,否则你可能会得到时髦的结果【参考方案2】:

首先你需要添加这个函数

func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool 
    return true 

那么你的功能没问题,但不需要 tableview 重新加载数据只需调用 tableview.beingUpdatestableview.endUpdates

func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) 
    if editingStyle == .delete 
       print("Deleted")
       self.catNames.remove(at: indexPath.row)
       self.tableView.beginUpdates()
       self.tableView.deleteRows(at: [indexPath], with: .automatic)
       self.tableView.endUpdates() 
    

【讨论】:

这是默认设置,添加它并不能解决 OP 遇到的任何崩溃问题。 没有理由使用 begin/endUpdates 来处理对表格视图的单个更改。【参考方案3】:

我给你的答案

func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool

     return true


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

    if editingStyle == .delete
    
        array.remove(at: indexPath.row)
        tblDltRow.reloadData()
    

你需要刷新表格

【讨论】:

根据 @rmaddy 从另一个答案重新加载仅删除的元素是一种不好的做法。而不是重新加载它应该类似于 self.tableView.deleteRows(at: [indexPath], with: .automatic)。您真的不知道单元格是如何工作或定义的。想象一个带有复杂自定义单元的长列表,可能带有图像,重新加载可能会强制下载或触发 @le0diaz,实际上今天我遇到了问题,我有一个表格视图,我们在其中显示用户列表,每个单元格中都有删除按钮。如果我删除第一行,它将从表视图中删除第一行,但如果我在删除第一行后删除第 10 行。删除按钮将有错误的索引,它正在从 tableview 中删除行。 嗨 可以问一下 moveRow 相关的问题吗? @le0diaz 这里有同样的问题。你怎么修好它的?我正在使用委托从单元格中调用删除函数。【参考方案4】:
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) 

    if editingStyle == .delete 

        self.animals.remove(at: indexPath.row)

        self.dataDisplayTbleView.reloadData()
    


【讨论】:

【参考方案5】:

Swift 4 中试试这个

func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool 
        return true
    
    func tableView(_ tableView: UITableView, commit editingStyle:   UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) 
        if (editingStyle == .delete) 
            arrStudentName.remove(at: indexPath.row)
            tableView.beginUpdates()
            tableView.deleteRows(at: [indexPath], with: .middle)
            tableView.endUpdates()
        
    

【讨论】:

提及这些方法属于什么协议总是一个好主意。在这种情况下,这两种方法都是 UITableViewDataSource。【参考方案6】:

**

为斯威夫特 3

**

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

        self.catNames.remove(at: indexPath.row)
        self.tableView.deleteRows(at: [indexPath], with: .automatic)
      
    

【讨论】:

【参考方案7】:
    self.tableView.beginUpdates()
    self.tableView.deleteRows(at: [ IndexPath(row: index, section: section) ], with: .fade)
    self.remove_object_from_model()
    self.tableView.endUpdates()

【讨论】:

beginUpdates 和 endUpdates 将在未来的版本中被弃用。【参考方案8】:

您不必重新加载 tableView。

在使用tableView.deleteRows(at: [IndexPath], with: UITableView.RowAnimation) 之前,您必须在numberOfRowsInSection 中确定要删除的行数

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int 

return //Your current number of rows - The number of rows to delete

    

通常,行数是数组中的项目数 (yourArray.count),这意味着您可以在删除单元格之前从该数组中删除项目,并且得到相同的结果。

【讨论】:

【参考方案9】:

对于 Swift 5

func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) 
      if editingStyle == .delete 
        print("Deleted")

        self.catNames.remove(at: indexPath.row)
        self.tableView.deleteRows(at: [indexPath], with: .automatic)
      
    

【讨论】:

以上是关于在 Swift 中从 UITableView 中删除一行?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Swift 中从 Core Data 中删除数据时删除 UITableView 行?

如何在 Swift / iOS 中从 UITableView 中删除行并从 UserDefaults 中更新数组

在 TableViewCell Swift 中从 Firebase 加载图像

在 Swift 中从 json 解析我的数据有啥问题?

Swift 3 - 在 Safari 中从 JSON 打开 URL

在 Swift 中从 TableView 拖放到另一个视图