Enabling & Configuring UITableView Edit Mode

If you’re presenting data to your users in a tableView, it is very likely you would want to add & remove rows from the table. In order to do this, UITableViews have a BOOL property called isEditing, which you can use to enter & exit edit mode.

Edit Mode on a UITableView is configured through the

- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath

and

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath

methods of the UITableView DataSource Protocol.

Enabling Edit Mode

Return YES for all IndexPath Sections / Rows you want Edit Mode enabled for.

- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath

{

// Return NO if you do not want the specified item to be editable.

if (indexPath.section == 0) {

if (indexPath.row == 0) {

return NO;

}

}

returnYES;


}

The code above will disable Edit Mode for Row 1 of the first Section, but will enable it for all other Sections/Rows.

Configuring Edit Mode – UI Controls:

There is no direct way to hook up a UIButton to a tableView, to enter into Edit Mode. Instead, set up an IBAction from the required UIButton, that does the following:

- (IBAction)enterEditMode:(id)sender {

if ([self.tableView isEditing]) {

// If the tableView is already in edit mode, turn it off. Also change the title of the button to reflect the intended verb (‘Edit’, in this case).

[self.tableViewsetEditing:NOanimated:YES];

[self.editButtonsetTitle:@"Edit"forState:UIControlStateNormal];

}

else {

[self.editButtonsetTitle:@"Done"forState:UIControlStateNormal];


// Turn on edit mode


[self.tableViewsetEditing:YESanimated:YES];

}

}

You do not need to do this though, if the user can only delete rows. Swipe-to-delete will be enabled by default if a tableView can be edited.

Configuring Edit Mode – The TableView:

The following code will affect how new Rows are added, and existing ones deleted.

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath

{

// Get the managedObjectContext from the AppDelegate (for use in CoreData Applications)

AppDelegate *appdelegate = [[UIApplication sharedApplicationdelegate];

NSManagedObjectContext *context = appdelegate.managedObjectContext;

if (editingStyle == UITableViewCellEditingStyleDelete) {

// Delete the row from the data source


YourObject *object = [self.dataSourceArray objectAtIndex:indexPath.row];

[self.dataSourceArray removeObjectAtIndex:indexPath.row];

// You might want to delete the object from your Data Store if you’re using CoreData

[context deleteObject:pairToDelete];

NSError *error;

[context save:&error];

// Animate the deletion

[tableView deleteRowsAtIndexPaths:[NSArrayarrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];


// Additional code to configure the Edit Button, if any

if (self.dataSourceArray.count == 0) {

self.editButton.enabled = NO;

self.editButton.titleLabel.text = @”Edit”;

}

}

elseif (editingStyle == UITableViewCellEditingStyleInsert) {

// Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view

YourObject *newObject = [NSEntityDescription insertNewObjectForEntityForName:@"Header" inManagedObjectContext:context];

newObject.value = @”value”;

[context save:&error];

[tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:indexPath]withRowAnimation:UITableViewRowAnimationFade];

if (self.dataSourceArray.count0) {

self.editButton.enabledYES;

}

}

}

Enabling Cell Selection during Edit Mode:

You need to change a setting in Interface Builder if you want to enable selections when editing (why this is not the default is anybody’s guess). Select the tableView in IB, and change the setting under ‘Editing’, to allow ‘Single Selection during Editing”.

Edit mode selection

Finally, if you need different behavior in your app when selecting cells during edit mode, you also need to change the didSelectRowAtIndexPath method, to handle this.

UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];

if ([cell isEditing] == YES) {

// Do something.

}

else {

// Do Something else.

}

And that’s it! A somewhat lengthy way to do something that should have been a lot easier. Hopefully, things will change for the better in iOS 6.

5 comments

Post a comment

You may use the following HTML:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>