【问题标题】:Deleting a Row from a UITableView in Swift?在 Swift 中从 UITableView 中删除一行?
【发布时间】: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在哪里了。当然它应该提供崩溃日志,但您建议的是最佳实践,而不是实际的根本原因。

标签: swift uitableview row


【解决方案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)
              }
            }
        

        【讨论】:

          猜你喜欢
          • 2017-01-28
          • 1970-01-01
          • 1970-01-01
          • 2017-05-24
          • 1970-01-01
          • 2023-04-05
          • 1970-01-01
          • 1970-01-01
          • 2018-03-13
          相关资源
          最近更新 更多