Uitableview 默认情况下,具有破坏性样式的UIContextualAction似乎会删除行
我看到的问题是,当我在Uitableview 默认情况下,具有破坏性样式的UIContextualAction似乎会删除行,uitableview,swipe,ios11,Uitableview,Swipe,Ios11,我看到的问题是,当我在completionHandler中使用.destromical和passtrue创建UIContextualAction时,似乎有一个默认操作用于删除该行 如果您从Xcode的模板创建一个新的Master Detail应用程序,并将此代码添加到MasterViewController override func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt ind
completionHandler
中使用.destromical
和passtrue
创建UIContextualAction
时,似乎有一个默认操作用于删除该行
如果您从Xcode的模板创建一个新的Master Detail应用程序,并将此代码添加到MasterViewController
override func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {
let testAction = UIContextualAction(style: .destructive, title: "Test") { (_, _, completionHandler) in
print("test")
completionHandler(true)
}
return UISwipeActionsConfiguration(actions: [testAction])
}
您刷卡的行将被删除。请注意,这里没有更新表视图的代码。此外,模型不会更新,如果向上滚动导致行被重新加载,它将重新出现
在这种情况下传递false
不会删除该行。或者使用.normal
样式和true
也不会删除该行
.destromical
和true
默认情况下会删除该行
有人能解释这种行为吗?为什么要删除该行?根据破坏性选项的文档:
删除数据或执行某种破坏性任务的操作
完成是为了表明行动是否成功。如果传递true,则意味着破坏性任务是成功的,因此应该删除该行
当破坏性操作发生时,您需要手动更新数据源,否则将导致滚动以使数据重新出现。您还需要告诉tableView数据已被删除
下面是一些显示工作示例的代码:
UIContextualAction(style: .destructive, title: "Delete") { [weak self] (_, _, completion) in
if self?.canDelete(indexPath) { // We can actually delete
// remove the object from the data source
self?.myData.remove(at: indexPath.row)
// delete the row. Without deleting the row or reloading the
// tableview, the index will be off in future swipes
self?.tableView?.deleteRows(at: [indexPath], with: .none)
// Let the action know it was a success. In this case the
// tableview will animate the cell removal with the swipe
completion(true)
} else { // We can't delete for some reason
// This resets the swipe state and nothing is removed from
// the screen visually.
completion(false)
}
}
然后我需要重新加载tableview
或调用deleteRows
,以便在下次刷卡时正确计算indexPath
如果我有10行,我刷第5行删除,之后的每一行都将被关闭一行,除非重新加载tableview
,或者tableview
以某种方式被告知该行已被删除。我同意以下回答:,但是请注意,如果使用的是NSFetchedResultsController,则可能会使事情变得复杂。对于破坏性UIContextualAction,调用completion(true)
似乎会删除该行,但NSFetchedResultsController的委托也会删除该行。因此,您很容易以这种方式结束错误。使用NSFetchedResultsController,我决定调用完成(false)
(关闭上下文菜单),不管操作是否成功,然后让代理负责删除表行,如果相应的对象已被删除。我无法在iOS 13中重现此问题。iOS 12及之前版本中的行为要么是一个bug,要么只是被撤销了(可能是因为它令人困惑)
在iOS 13中,如果您通过调用completion(true)
从破坏性
操作返回,而不做任何事情,则不会发生任何事情,这就是问题的结束。不会为您删除单元格。使用下面的标志禁用完全滑动
使用完全滑动执行第一个操作
默认情况下,它将自动执行UISwipeActionsConfiguration中配置的第一个操作。因此,如果要禁用完全滑动删除,请将“performsFirstActionWithFullSwipe”设置为false
func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {
let test = UIContextualAction(style: .destructive, title: "test") { (action, view, completion) in
// Your Logic here
completion(true)
}
let config = UISwipeActionsConfiguration(actions: [test])
config.performsFirstActionWithFullSwipe = false
return config
}
希望这能解决您的问题。按照此代码,我遇到了一个崩溃。原因是--您不应该自己删除此行self?.tableView?.deleteRows中的行(位于:[indexPath],带:.none)。当您调用completion(true)时,UIKit会删除行。的确,iOS12和iOS13的行为不同,我认为这是一个bug,