I just implemented trailingSwipeActionsConfigurationForRowAt
and leadingSwipeActionsConfigurationForRowAt
to add swipe actions to my UITableViewCell
s.
func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration
func tableView(_ tableView: UITableView, leadingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration
This triggers (on my UITableViewController) func setEditing(_ editing: Bool, animated: Bool)
to be called with editing = true
, which in turn also triggers my editing animation and other changes that I want when going into edit mode. (The contextual actions are not related to editing/deleting).
I don't want this, but have yet to find a way to disable this behaviour, even just detecting that setEditing
is called via the swipe actions.
Any ideas?
I was able to solve this by triggering the "real" edit mode differently.
On my UITableViewController
:
class MyTableViewController: UITableViewController {
var realEditMode: Bool = false
func setRealEditing(_ editing: Bool) {
realEditMode = editing
setEditing(realEditMode, animated: true)
}
// See Note 1 below
@available(iOS 11.0, *)
override func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration {
guard let item = itemForIndexPath(indexPath) else {
return UISwipeActionsConfiguration(actions: [])
}
if realEditMode {
return UISwipeActionsConfiguration(actions: [
buildActionConfiguration(.delete, fromIndexPath: indexPath)
])
} else {
return UISwipeActionsConfiguration(actions: [
buildActionConfiguration(.read, fromIndexPath: indexPath)
])
}
}
@available(iOS 11.0, *)
func buildActionConfiguration(_ action: MyCellActionEnum, fromIndexPath indexPath: IndexPath) -> UIContextualAction {
// logic to build `UIContextualAction`
}
}
And in my UITableViewCell
check if the editing
flag is set by manual triggering or by swipe edit triggering:
class MyCell: UITableViewCell {
var myTableViewController: MyTableViewController?
override func setEditing(_ editing: Bool, animated: Bool) {
if editing && !(myTableViewController?.realEditMode ?? true) {
return
}
super.setEditing(editing, animated: animated)
}
}
Then on the edit buttons in the UI I changed setEditing(true/false, animated: true)
to setRealEditing(true/false)
instead.
One problem I found was that when using trailingSwipeActionsConfigurationForRowAt
was that the delete button (⛔️) didn't work anymore. Tapping it did not trigger the confirmation swipe.
I found that there had to exist a trailingSwipeActionsConfigurationForRowAt
with a UIContextualAction
that was initialized with UIContextualAction(style: .destructive)
(i.e had destructive style). This is the item that is then used for displaying the delete confirmation.
However I did not want that item to be visible when the regular swipe actions were used, so to only show it one "real edit mode" I used the realEditMode
flag.
This worked for me and didn't seem too hacky. If anything more official pops up I'm more than happy to change the accepted answer.