20
votes

How can I implement a button on the navigation bar whereby the user would be able to reorder & delete rows of a UITableView?

Do I have to create my own toolbar button to have the Edit/Done button for my UITableView?

8

8 Answers

48
votes

Just add this line in viewDidLoad of your UITableViewController

self.navigationItem.leftBarButtonItem = self.editButtonItem;

It will work if your table view superview is UINavigationController. This line will add button that will push table in edit mode and out of it.

21
votes

What's generally done is you create your own custom BarbuttonItem and then assign this button as right navigation bar button item:

UIBarButtonItem *barButtonItem=[[UIBarButtonItem alloc]initWithTitle:@"Edit"
                                                               style:UIBarButtonItemStylePlain
                                                              target:self 
                                                              action:@selector(toggleEdit)];

self.navigationItem.rightBarButtonItem = barButtonItem;   
[barButtonItem release];

Here's the toggleEdit method:

-(void)toggleEdit{
          [self.tableView setEditing:!self.tableView.editing animated:YES]; 

          if (self.tableView.editing) 
              [self.navigationItem.rightBarButtonItem setTitle:@"Done"]; 
          else 
             [self.navigationItem.rightBarButtonItem setTitle:@"Edit"];  
}
6
votes
UIButton *btnname=[UIButton buttonWithType:UIButtonTypeSystem];
[btnname setFrame:CGRectMake(0,0,110,35)];
[btnname setFont:[UIFont boldSystemFontOfSize:18]];
[btnname setTitle: @"Delete" forState: UIControlStateNormal];
[btnname setTitleColor:UIColorFromRGB(0xCC0707)        forState:UIControlStateNormal];
btnname.backgroundColor=UIColorFromRGB(0xE6E7E8);
btnname.showsTouchWhenHighlighted = YES;
[btnname addTarget:self
            action:@selector(toggleEdit)
forControlEvents:UIControlEventTouchDown];
UIBarButtonItem *barItem = [[UIBarButtonItem alloc] initWithCustomView:btnname];
self.navigationItem.rightBarButtonItem = barItem;


-(void)toggleEdit{
    [self.tableView setEditing:!self.tableView.editing animated:YES];

    if (self.tableView.editing)
         [btnname setTitle: @"Done" forState: UIControlStateNormal];
    else
         [btnname setTitle: @"Delete" forState: UIControlStateNormal];
}
4
votes

Here is a Swift version I used:

func clickedEditButton(button: UINavigationItem) {
    tableView.setEditing(!tableView.editing, animated: true)

    if tableView.editing {
        button.rightBarButtonItem?.title = "Done"
    } else {
        button.rightBarButtonItem?.title = "Edit"
    }
}
0
votes

If you want your button to switch between the blue "Done" color and the plain "Edit" color, you can set the rightBarButtonItem to either UIBarButtonItemStyleDone for blue, or UIBarButtonItemStylePlain for plain like this

self.navigationItem.rightBarButtonItem.style = UIBarButtonItemStyleDone;
0
votes

Make sure you need to initialize the title first. By storyBoard,

enter image description here

after that,

@IBAction func editBtnPressed(_ sender: UIBarButtonItem) {
        tableView.setEditing(!tableView.isEditing, animated: true)

        if tableView.isEditing {
            self.editButton.title = "Done"
        } else {
            self.editButton.title = "Edit"
        }
    }
0
votes

This is being used in the case where on non-UITableViewController UIViewController has an outlet to the UITableView in question.

As mentioned above, you cannot change the values in the bar button item, particularly if it's a system item. If you desire, you can create the two items and have them available in ivars (like the UITableViewController). It's not really that much execution time to create a new one though, especially if it may never be used.

Swift 5

@IBOutlet var table: UITableView!

@IBAction func toggleTableEdit(sender:UIBarButtonItem) {
    table.setEditing(!table.isEditing, animated: true)
    navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: (table.isEditing) ? .done : .edit, target: self, action: #selector(toggleTableEdit(sender:)))
}
0
votes

@Nekto's answer is correct, you need to add this line to your viewDidLoad implementation:

navigationItem.leftBarButtonItem = editButtonItem

However, this new "Edit" button can work not only with subclasses of UITableViewController, but with any subclass of UIViewController. You just have to implement the setEditing method yourself.

For example, here is how it works in a UIViewController with a tableView:

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

    tableView.isEditing = editing // <-- toggle the tableView's editing mode
}