在 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 3 和 Swift 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.beingUpdates
和 tableview.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 加载图像