Currently I am using NSFetchedResultsController to handle tableviews. I am wondering is there any way to add additional buttons like the delete button in swipe operation?
I am thinking about to subclass it. But find nothing relevant in help docs to my problems.
Thanks in advance.
Your title is misleading. NSFetchedResultsController has no relevance to your end goal. Subclassing would just create more work than necessary, what you want to look into is UITableViewRowAction
. This handles very easily & similarly to the new UIAlertController
, so you should feel extremely comfortable with this if you've already dabbled with the UIAlertController
A brief synopsis (straight from the docs) of UITableViewRowAction
:
Asks the delegate for the actions to display in response to a swipe in the specified row. (required) Use this method when you want to provide custom actions for one of your table rows. When the user swipes horizontally in a row, the table view moves the row content aside to reveal your actions. Tapping one of the action buttons executes the handler block stored with the action object. If you do not implement this method, the table view displays the standard accessory buttons when the user swipes the row.
A couple notes before you begin :
Regardless, to implement a custom UITableViewRowAction
you must first ensure your table is editable by calling the following methods:
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
//Obviously, if this returns no, the edit option won't even populate
return YES;
}
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
//Nothing gets called here if you invoke `tableView:editActionsForRowAtIndexPath:` according to Apple docs so just leave this method blank
}
At minimum, those are the two methods that need to be declared before moving on.
To actually customize your row action buttons, follow the general guideline as follows:
STEP 1 implement the tableView:editActionsForRowAtIndexPath:
method
-(NSArray *)tableView:(UITableView *)tableView editActionsForRowAtIndexPath:(NSIndexPath *)indexPath {
}
As you can see, it's an instance method of type NSArray, so you have to return an array.
STEP 2 Add action objects to pass in the array. An example:
{
UITableViewRowAction *delete = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleDefault title:@"Delete" handler:^(UITableViewRowAction *action, NSIndexPath *indexPath)
{
// Delete something here
}];
UITableViewRowAction *more = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleDefault title:@" More " handler:^(UITableViewRowAction *action, NSIndexPath *indexPath)
{
//Do whatever here : just as an example :
[self presentUIAlertControllerActionSheet];
}];
}
You can alter a few properties for these row actions, but see the documents for complete customization options:
To customize the row action background colors, simply preform it like most other actions within buttons:
delete.backgroundColor = [UIColor redColor];
more.backgroundColor = [UIColor colorWithRed:0.188 green:0.514 blue:0.984 alpha:1]; //arbitrary color
STEP 3 As mentioned before you have to return an array in the instance method so your complete code should resemble the following :
-(NSArray *)tableView:(UITableView *)tableView editActionsForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewRowAction *delete = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleDefault title:@"Delete" handler:^(UITableViewRowAction *action, NSIndexPath *indexPath)
{
// Delete something here
}];
delete.backgroundColor = [UIColor redColor];
UITableViewRowAction *more = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleDefault title:@" More " handler:^(UITableViewRowAction *action, NSIndexPath *indexPath)
{
//Just as an example :
[self presentUIAlertControllerActionSheet];
}];
more.backgroundColor = [UIColor colorWithRed:0.188 green:0.514 blue:0.984 alpha:1];
return @[delete, more]; //array with all the buttons you want. 1,2,3, etc...
}
For further reference : LINK TO DOCUMENTATION
EDITED FOR SWIFT SYNTAX
override func tableView(tableView: UITableView, editActionsForRowAtIndexPath indexPath: NSIndexPath) -> [AnyObject]? {
var delete = UITableViewRowAction(style: UITableViewRowActionStyle.Default, title: "Delete" , handler: { (action:UITableViewRowAction!, indexPath:NSIndexPath!) -> Void in
//Do something
})
delete.backgroundColor = UIColor.redColor()
var more = UITableViewRowAction(style: UITableViewRowActionStyle.Default, title: "More" , handler: { (action:UITableViewRowAction!, indexPath:NSIndexPath!) -> Void in
//Do something
})
more.backgroundColor = UIColor.blueColor()
return [delete, more]
}