38

I wanted to change the color of minus button and delete button of UITableViewCell when click on edit button or swiping UITableView rows. I have implemented this code so far :

-(IBAction)doEdit:(id)sender
{

    [[self keyWordsTable] setEditing:YES animated:NO];
}

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
    if (editingStyle == UITableViewCellEditingStyleDelete) {

}
2
  • check this: stackoverflow.com/questions/1615469/…
    – Ilario
    Commented Nov 29, 2013 at 17:28
  • 4
    Seems like you never got an answer on how to change the color of the actual minus button, just the confirmation delete button.
    – SAHM
    Commented Mar 16, 2017 at 0:52

5 Answers 5

101

iOS 8 and 9 (props to this post)


Note: If you are working with an existing iOS 7 project, you'll need to update the target to iOS 8 to get this functionality. Also remember to set the UITableviewDelegate.

All the magic now happens here (as many buttons as you want too!!!!):

 -(NSArray *)tableView:(UITableView *)tableView editActionsForRowAtIndexPath:(NSIndexPath *)indexPath {
 UITableViewRowAction *button = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleDefault title:@"Button 1" handler:^(UITableViewRowAction *action, NSIndexPath *indexPath)
    {
        NSLog(@"Action to perform with Button 1");
    }];
    button.backgroundColor = [UIColor greenColor]; //arbitrary color
    UITableViewRowAction *button2 = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleDefault title:@"Button 2" handler:^(UITableViewRowAction *action, NSIndexPath *indexPath)
                                    {
                                        NSLog(@"Action to perform with Button2!");
                                    }];
    button2.backgroundColor = [UIColor blueColor]; //arbitrary color

    return @[button, button2];
}

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
// you need to implement this method too or nothing will work:

}
 - (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
    {
        return YES;
    }


(iOS 7)


**activate the delete button on swipe**

// make sure you have the following methods in the uitableviewcontroller

    - (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
    {
        return YES;
    }
    - (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
    {
        NSLog(@"You hit the delete button.");
    }

set custom text label instead of delete.

-(NSString *)tableView:(UITableView *)tableView titleForDeleteConfirmationButtonForRowAtIndexPath:(NSIndexPath *)indexPath
{
    return @"Your Label";
}

set custom color for button part 1 - warning, this technically involves poking at the private apple API. However, you are not prevented from modifying a subview using a public method search that is part of UIKIT.

Create a uitableviewcell class (see also https://stackoverflow.com/a/22350817/1758337 )

- (void)layoutSubviews
{
    [super layoutSubviews];
    for (UIView *subview in self.subviews) {
        //iterate through subviews until you find the right one...
        for(UIView *subview2 in subview.subviews){
            if ([NSStringFromClass([subview2 class]) isEqualToString:@"UITableViewCellDeleteConfirmationView"]) {
                //your color
                ((UIView*)[subview2.subviews firstObject]).backgroundColor=[UIColor blueColor];
            }
        }
    }    
}

Another note: there's no guarantee this approach will work in future updates. Also beware that mentioning or using the private UITableViewCellDeleteConfirmationView class may lead to AppStore rejection.

set custom color for button part 2

back in your uitableviewcontroller

- (void)tableView:(UITableView *)tableView willBeginEditingRowAtIndexPath:(NSIndexPath *)indexPath
{
    [YourTableView reloadData];
}

(The alternate color won't be called until the next time layoutSubviews is called on the tablecell, so we ensure this happens by reloading everything.)

9
  • Will this work with iOS 7.2? 7.3? 8.0b1? 8.0b3? Also, using UITableViewCellDeleteConfirmationView in your code is a sure way to have your app rejected.
    – Léo Natan
    Commented Mar 14, 2014 at 15:07
  • The only change from 6 to 7 was the naming convention--from UITableViewCellDeleteConfirmationControl to UITableViewCellDeleteConfirmationView. I'm not doing anything other than finding the view and then changing its background. Plenty of apps have used this technique prior. If Apple says no, it's not a big worry for me. The rest of the techniques are kosher and in the documentation :). Anyways, I've tried other solutions such as SWTableCells, but found the precision lacking compared to the baked in apple button. I just don't want a red button because of the apps color scheme.
    – timothykc
    Commented Mar 14, 2014 at 15:44
  • You should at least attempt to hide the use of private API. Also, the private view hierarchy between iOS6 and iOS7 table view cells has changed significantly. Your subview traversal, while working for now, may or may not break with every future release. But the worst in your post is the blatant use of private API.
    – Léo Natan
    Commented Mar 14, 2014 at 16:24
  • 1
    Thanks for the feedback and warnings. They are appreciated even though I'm going to throw caution the wind anyways. I'm going to edit the answer so that anyone else treading down understands that it's caveat emptor. Regarding if it breaks down the road, the only real loss is color, and if I have to code a custom solution then, so be it :)
    – timothykc
    Commented Mar 14, 2014 at 21:41
  • 1
    Note, you no longer need to implement commitEditingStyle , the UITableViewRowAction's handler is called instead Commented Jul 21, 2016 at 12:18
23

Swift Example (iOS 8)

UITableViewDelegate docs (editActionsForRowAtIndexPath method)

Return Value

An array of UITableViewRowAction objects representing the actions for the row. Each action you provide is used to create a button that the user can tap.

Discussion

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.

Working example in Swift:

@available(iOS 8.0, *)
func tableView(tableView: UITableView, editActionsForRowAtIndexPath indexPath: NSIndexPath) -> [UITableViewRowAction]? {
    let button1 = UITableViewRowAction(style: .Default, title: "Happy!") { action, indexPath in
        print("button1 pressed!")
    }
    button1.backgroundColor = UIColor.blueColor()
    let button2 = UITableViewRowAction(style: .Default, title: "Exuberant!") { action, indexPath in
        print("button2 pressed!")
    }
    button2.backgroundColor = UIColor.redColor()
    return [button1, button2]
}

func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool {
    return true
}
func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
}
1
  • 2
    And the minus button (this was asked too)?
    – User
    Commented May 26, 2018 at 15:44
3

fist time you call willTransitionToState in .m (customcell)

- (void)willTransitionToState:(UITableViewCellStateMask)state{
    NSLog(@"EventTableCell willTransitionToState");
    [super willTransitionToState:state];
    [self overrideConfirmationButtonColor];
}

Check version iOS, it's here, i'm using iOS 7 - iOS8

//at least iOS 8 code here
- (UIView*)recursivelyFindConfirmationButtonInView:(UIView*)view
{
    if (floor(NSFoundationVersionNumber) > NSFoundationVersionNumber_iOS_7_1) {
        // iOS 8+ code here
        for(UIView *subview in view.subviews) {

            if([NSStringFromClass([subview class]) rangeOfString:@"UITableViewCellActionButton"].location != NSNotFound)
                return subview;

            UIView *recursiveResult = [self recursivelyFindConfirmationButtonInView:subview];
            if(recursiveResult)
                return recursiveResult;
        }
    }

    else{
        // Pre iOS 8 code here
        for(UIView *subview in view.subviews) {
            if([NSStringFromClass([subview class]) isEqualToString:@"UITableViewCellDeleteConfirmationButton"]) return subview;
            UIView *recursiveResult = [self recursivelyFindConfirmationButtonInView:subview];
            if(recursiveResult) return recursiveResult;
        }
    }
    return nil;


}

-(void)overrideConfirmationButtonColor
{

    dispatch_async(dispatch_get_main_queue(), ^{
        UIView *confirmationButton = [self recursivelyFindConfirmationButtonInView:self];
        if(confirmationButton)
        {
            UIColor *color = UIColorFromRGB(0xFF7373);
            confirmationButton.backgroundColor = color;

        }
    });
}
0
2

Not possible using public API.

For the delete button, you can use a custom implementation, such as SWTableViewCell, to change the color of the button, as well as add others.

2
  • It is in iOS 8.2 (check the UITableViewDelegate documentation)
    – clearlight
    Commented Jan 30, 2015 at 22:35
  • @binarystar Old answer.
    – Léo Natan
    Commented Jan 30, 2015 at 23:49
1

Old Question, but am sure there are some people who support iOS 7. To change the delete button background colour, you need to create "UITableViewCell" class or extend it. then you can use

- (void)layoutSubviews
{
    [super layoutSubviews];
    for (UIView *subview in self.subviews) {
        for(UIView *childView in subview.subviews){
            if ([childView isKindOfClass:[UIButton class]]) {
                childView.backgroundColor = [UIColor blueColor];
            }
        }
    }
}

Not the answer you're looking for? Browse other questions tagged or ask your own question.