2

Title essentially says it all.

I have a UITableView and I want the RightBarButtonItem item to disappear while the UITableView is in edit mode. Unfortunately, all of the answers that I have found so far suggest setting the button to nil... which won't work for me because I do not want to get rid of the button and the reference to it, just hide it while the UITableView is in edit mode.

What I'm having trouble figuring out what to do, then, is:

  1. Detect when the UITableView has entered editing mode
  2. Hiding the RightBarButtonItem (not removing it entirely)
  3. Detect when the UITableView has left editing mode (so the button can reappear)

Any help would be appreciated, thank you!

Jay Bhalani
  • 4,142
  • 8
  • 37
  • 50
SwiftHacker
  • 149
  • 2
  • 13

3 Answers3

5

My working solution for anyone who needs it:

override func setEditing(editing: Bool, animated: Bool) {
    if (editing) {
        super.setEditing(true, animated: true)
        self.navigationItem.rightBarButtonItem!.enabled = false
    } else {
        super.setEditing(false, animated: true)
        self.navigationItem.rightBarButtonItem!.enabled = true
    }
}

Make sure to set the super.setEditing before and after editing starts in order to preserve the functionality of the edit button.

In addition, if you don't want the UITableView to remain in edit mode when the user leaves the UITableView and doesn't click "done" first, add the following function:

override func viewWillDisappear(animated: Bool) {
    super.viewWillDisappear(true)
    if (editing) {
        editing = false
    }
}
SwiftHacker
  • 149
  • 2
  • 13
1

You can use an optional datasource method to detect when a row is being edited, tableView(_:canEditRowAtIndexPath:)

And inside that method, you can either hide or disable the bar button item (disabling is probably the friendlier thing to do, in terms of the UI and code). There is no hidden property on a bar button, so to properly hide it means you potentially do some grody coding to temporarily remove or make it disappear.

Anyways, I suggest something like:

func tableView(tableView: UITableView!, canEditRowAtIndexPath indexPath: NSIndexPath!) -> Bool {
    self.navigationItem.rightBarButtonItem.enabled = false
    return true
}
Community
  • 1
  • 1
Michael Dautermann
  • 88,797
  • 17
  • 166
  • 215
  • Thank you for your prompt reply! Disabling the button will work just as well. However, there is one issue with the tableView(_:willBeginEditingRowAtIndexPath:) method: the only time my button is disabled is when I slide across a row to edit (delete) it... the button is not disabled when the "edit" button is pressed (which also puts the UITableView in edit mode). – SwiftHacker Jul 29 '15 at 06:57
  • Yeah, when the `willBeginEditingRowAtIndexPath` method is called, it's when you actually start to really do the editing of the row. To catch it earlier, [we need to implement a table's datasource method](http://stackoverflow.com/questions/1776045/how-to-detect-edit-mode-on-iphone-uitableview). – Michael Dautermann Jul 29 '15 at 07:08
  • Perfect, that helped. I'll post my final solution below for anyone else that needs it. – SwiftHacker Jul 29 '15 at 07:19
1

I had same challenge with two different bar buttons which I needed to hide and show on some conditions. First was "edit" button to enter editing mode on my view and second was "done" to save changes. So they had to appear interchangeably.

I made an extenstion to UINavigationItem class where implemented two methods. One to delete item from bar. Second to add item to bar. As a parameter to these methods I passed IBOutlets of the items which I made strong so they would not deallocate when item is removed from bar

extension UINavigationItem {

  func deleteFromRightBar(item: UIBarButtonItem) {
    // make sure item is present 
    guard let itemIndex = self.rightBarButtonItems?.index(of: item) else {
      return
    }
    // remove item
    self.rightBarButtonItems?.remove(at: itemIndex)
  }

  func addToRightBar(item: UIBarButtonItem) {
    // make sure item is not present
    guard self.rightBarButtonItems?.index(of: item) == nil else {
      return
    }
    // add item
    self.rightBarButtonItems?.append(item)
  }
}

I used these methods like that

navigationItem.deleteFromRightBar(item: doneButton)
navigationItem.addToRightBar(item: editButton)