Gallaugher Gallaugher - 24 days ago 4x
iOS Question

What is triggered when "Done" is pressed after changing from "Edit" in UINavigationItem bar for UITableViewController?

Short: In Swift/iOS, when does the "Done" (which was previously "Edit") nav bar button trigger when getting out of the UITableViewController "Edit" mode? When the user presses "Done" I'd like to enable a "+" button in my UINavigationItem bar so the user can once-again add rows by migrating to another view controller.

Longer: When a UITableViewController is showing below a UINavigationItem nav bar, there is an "Edit" button which turns into "Done" after it's clicked to enable deletes & move/drags. Works great when this button is enabled via uncommenting code in viewDidLoad() generated as part of the UITableViewController class:

self.navigationItem.leftBarButtonItem = self.editButtonItem

I've got my move/drags & deletes working fine, but I want to appropriately disable my "+" button (addBarButton, used for navigating to another view controller to add a new row) while the user is in the Edit mode. I'd then like to re-enable addBarButton after the user has clicked "Done" (which turns back into "Edit").

It looks like disabling addBarButton during the func tableView(_ tableView: UITableView, canMoveRowAt indexPath: IndexPath) is correct. If I read Apple's docs right, this is triggered when user presses Edit in the nav bar. What I don't know is what is triggered when the user presses "Done" (the button formerly labeled "Edit"). If I enable my addBarButton "+" button after the func tableView with moveRowAt, this enables addBarButton before the user has pressed "Done".

The Apple doc I'm referencing is at:

Apologies if I'm missing something obvious. Thx


The answer is right in the description for the UIViewController editButtonItem documentation:

If one of the custom views of the navigationItem property is set to the returned object, the associated navigation bar displays an Edit button if isEditing is false and a Done button if isEditing is true. The default button action invokes the setEditing(_:animated:) method.

The last sentence is the key. You should override the setEditing(_:animated:) method in your table view controller subclass. Be sure you call the super implementation and then perform whatever custom action you want based on whether the controller is entering or exiting editing mode.

override func setEditing(_ editing: Bool, animated: Bool) {
    super.setEditing(editing, animated: animated)

    if (editing) {
        // User tapped the Edit button, do what you need
    } else {
        // User tapped the Done button, do what you need