33

I want put the icon (image) instead of text in swipe actions in tableviewCell in Swift.

But i dont how to put the image instead of title text?

My code is below:

func tableView(tableView: UITableView, editActionsForRowAtIndexPath indexPath: NSIndexPath) -> [AnyObject]?  {

    var shareAction = UITableViewRowAction(style: UITableViewRowActionStyle.Default, title: "Share" , handler: { (action:UITableViewRowAction!, indexPath:NSIndexPath!) -> Void in
        // 2
        let shareMenu = UIAlertController(title: nil, message: "Share using", preferredStyle: .ActionSheet)

        let twitterAction = UIAlertAction(title: "Twitter", style: UIAlertActionStyle.Default, handler: nil)
        let cancelAction = UIAlertAction(title: "Cancel", style: UIAlertActionStyle.Cancel, handler: nil)

        shareMenu.addAction(twitterAction)
        shareMenu.addAction(cancelAction)


        self.presentViewController(shareMenu, animated: true, completion: nil)
    })
    // 3
    var rateAction =    (style: UITableViewRowActionStyle.Default, title: "rate",im , handler: { (action:UITableViewRowAction!, indexPath:NSIndexPath!) -> Void in
        // 4

        let rateMenu = UIAlertController(title: nil, message: "Rate this App", preferredStyle: .ActionSheet)

        let appRateAction = UIAlertAction(title: "Rate", style: UIAlertActionStyle.Default, handler: nil)
        let cancelAction = UIAlertAction(title: "Cancel", style: UIAlertActionStyle.Cancel, handler: nil)

        rateMenu.addAction(appRateAction)
        rateMenu.addAction(cancelAction)


        self.presentViewController(rateMenu, animated: true, completion: nil)
    })

    // 5
    return [shareAction,rateAction]
}

Can you someone pls help me on this?

Thanks in advance

4
  • There are currently no public APIs for this customization. The only editable properties are the title string, the background color, button style and background effect. You will have to create a custom format or use a third party library Commented Jan 10, 2015 at 1:49
  • did you ever figure this out? Commented Jul 18, 2015 at 19:59
  • stackoverflow.com/a/38655903/4928945 Commented Jul 29, 2016 at 12:11
  • Answered stackoverflow.com/a/46647562/7576100 Commented Oct 9, 2017 at 13:27

8 Answers 8

53

There are two ways you can achieve this.

  • Use Unicode characters in your text, if it serves your purpose, However unicode characters are limited set.
  • Use emojis provided that it serve your purpose.

This is how you do it in the code

 override func tableView(tableView: UITableView, editActionsForRowAtIndexPath indexPath: NSIndexPath) -> [UITableViewRowAction]? {
    let delete = UITableViewRowAction(style: .Default, title: "\u{267A}\n Delete") { action, index in
        print("more button tapped")
        self.tableView(tableView, commitEditingStyle: UITableViewCellEditingStyle.Delete, forRowAtIndexPath: indexPath)
    }
    delete.backgroundColor = UIColor(rgba: "#ef3340")

    let apply = UITableViewRowAction(style: .Default, title: "\u{2606}\n Like") { action, index in
        print("favorite button tapped")
        self.tableView(tableView, commitEditingStyle: UITableViewCellEditingStyle.Insert, forRowAtIndexPath: indexPath)
    }
    apply.backgroundColor = UIColor.orangeColor()

    let take = UITableViewRowAction(style: .Normal, title: "\u{2605}\n Rate") { action, index in
        print("share button tapped")
        self.tableView(tableView, commitEditingStyle: UITableViewCellEditingStyle.None, forRowAtIndexPath: indexPath)
    }
    take.backgroundColor = UIColor(rgba: "#00ab84")

    return [take, apply, delete]
}

This is what I could achieve by above mentioned ways -

enter image description here

Sign up to request clarification or add additional context in comments.

8 Comments

Legend! This most of the times beats all third party solutions. I've got a question though, do you know where to find flat (similar to what you used) style emojicons? I looked around, and any emojicon that apple also has is shown as 3d (same as when you type a message). Is there any way to make them flat or show the original style? Like this website? graphemica.com/search?q=report
I do not know anything else then the emojis already available in Xcode which you can insert by using ctrl+cmd+space, since in this list most of them are 3d I prefer to use unicode character from site similar to what you have pointed. So to answer Sorry I have no idea how to make the emojis flat. :(
lol :) I didn't know that you can access them so easily! I looked all over the internet!! I think I'll do the same and follow it! But I'll open a question just in case someone else knows it! I'll update here with the link. Thanks for the tip! :)
Sure feel free to do that.
The question has been asked :) : stackoverflow.com/questions/34577378/…
|
27

In iOS 11, Apple provides a way to help us do that. There are 2 functions you need to implement to swipe cell to left or right

public func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration?
public func tableView(_ tableView: UITableView, leadingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration?

For example:

func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {
        let deleteAction = UIContextualAction(style: .normal, title:  "", handler: { (ac:UIContextualAction, view:UIView, success:(Bool) -> Void) in
            // Call edit action

            // Reset state
            success(true)
        })
        deleteAction.image = UIImage(named: "ic_delete")
        deleteAction.backgroundColor = .red
        return UISwipeActionsConfiguration(actions: [deleteAction])
    }

If you want to apply it for iOS < 11.0, you can do it by a tricky way

func tableView(tableView: UITableView, editActionsForRowAtIndexPath indexPath: NSIndexPath) -> [UITableViewRowAction]? {

        let deleteAction = UITableViewRowAction(style: .default, title: "") { action, indexPath in
            // Handle delete action
        }
        (UIButton.appearance(whenContainedInInstancesOf: [UIView.self])).setImage(UIImage(named: "ic_delete"), for: .normal)
        return [deleteAction]
    }

3 Comments

It works fine here, but below iOS 11, is there any way to apply this to multiple actions in one row? I've assigned two actions, but each one needs its one image.
@nontomatic Well, I think there isn't any way to do multiple actions in one row using 'tricky' way :(
When you are using .jpg in trailingSwipeActions... and get a blank white rectangle instead of the image, try to use a .png - that fixed it for me :)
3

Not Swift, but for anybody else who lands here looking for a solution... I've got good results with the following simple subclass:

@interface GSBTableViewRowAction : UITableViewRowAction
@property UIImage *icon;
@property UIFont *font;
+ (instancetype)rowActionWithStyle:(UITableViewRowActionStyle)style title:(NSString *)title icon:(UIImage*)icon handler:(void (^)(UITableViewRowAction *action, NSIndexPath *indexPath))handler;
@end

@implementation GSBTableViewRowAction
+ (instancetype)rowActionWithStyle:(UITableViewRowActionStyle)style title:(NSString *)title icon:(UIImage*)icon handler:(void (^)(UITableViewRowAction *action, NSIndexPath *indexPath))handler
{
    if (title.length) title = [@"\n" stringByAppendingString:title]; // move title under centerline; icon will go above
    GSBTableViewRowAction *action = [super rowActionWithStyle:style title:title handler:handler];
    action.icon = icon;
    return action;
}

- (void)_setButton:(UIButton*)button
{
    if (self.font) button.titleLabel.font = self.font;
    if (self.icon) {
        [button setImage:[self.icon imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate] forState:UIControlStateNormal];
        button.tintColor = button.titleLabel.textColor;
        CGSize titleSize = [button.titleLabel.text sizeWithAttributes:@{NSFontAttributeName:button.titleLabel.font}];
        button.imageEdgeInsets = UIEdgeInsetsMake(-(titleSize.height/2 + 5), 0, 0, -titleSize.width); // +5px gap under icon
    }

The rowActionWithStyle:title:icon:handler is really just a convenience method - the 'secret sauce' is overriding the (private?) _setButton method [credit to Jayesh for this!].

This will give you an icon centered over the title, or just the icon alone if you leave the title nil. Unfortunately, you cant fiddle with the position of the title using button.titleEdgeInsets, like you can imageEdgeInsets, so best I can do is put the title immediately under the centerline (hence the '\n') with a small gap under the icon (5px above). Results look like

row action with title + icon

As a bonus, you can also change the title font, to say something smaller, by setting the new font property. eg the above 'Add' action was accomplished with

GSBTableViewRowAction *add = [GSBTableViewRowAction rowActionWithStyle:UITableViewRowActionStyleNormal
                                                               title:@"Add"
                                                                icon:[UIImage imageNamed:@"Today-25"]
                                                             handler:^(UITableViewRowAction *action, NSIndexPath *indexPath){
                                                                 [self addToCalendar:self];
                                                                 [tableView setEditing:NO animated:YES];
                                                             }];
add.font = [UIFont preferredFontForTextStyle:UIFontTextStyleFootnote];
add.backgroundColor = UIColor.orangeColor;

Caveat: _setButton is private API, so YMMV... We're all hoping Apple will expose a public API to do what they apparantly do in their Mail.app [sic]

1 Comment

Were Apple OK approving this?
3

Try this

func tableView(tableView: UITableView, editActionsForRowAtIndexPath indexPath: NSIndexPath) -> [UITableViewRowAction]? {

    let remove = UITableViewRowAction(style: .Default, title: "      ") { action, indexPath in


        print("delete button tapped")
    }

    remove.backgroundColor = UIColor(patternImage: UIImage(named: "Delete")!)

    return [remove]
}

enter image description here

4 Comments

Make sure that you explain how it works, and show in your code how to do it. Your current code does not cause an icon to show.
what size was the icon?
I'm doing the same thing, but it doesn't work. look at my swipe action : imgur.com/a/bw3O5
@Hogdotmac Please see my answer for iOS 11
3

Check below working code

func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> \[UITableViewRowAction\]? {


            let backView = UIView(frame: CGRect(x: 0, y: 0, width: 100, height: tableView.frame.size.height))
            backView.backgroundColor = UIColor(red: 239/255.0, green: 34/255.0, blue: 91/255.0, alpha: 1.0)

            let frame = tableView.rectForRow(at: indexPath)


            let myImage = UIImageView(frame: CGRect(x: 20, y: frame.size.height/2-20, width: 35, height: 35))
            myImage.image = UIImage(named: "delete_white")!
            backView.addSubview(myImage)

            let imgSize: CGSize = tableView.frame.size
            UIGraphicsBeginImageContextWithOptions(imgSize, false, UIScreen.main.scale)
            let context = UIGraphicsGetCurrentContext()
            backView.layer.render(in: context!)
            let newImage: UIImage = UIGraphicsGetImageFromCurrentImageContext()!
            UIGraphicsEndImageContext()

            let deleteAction = UITableViewRowAction(style: .destructive, title: "           ") {
                (action, indexPath) in
                self.deleteCartItem(indexPath: indexPath )
                self.addWebtrendsForCart(path: "/Basket/EditBasket", description: "Edit Basket")
            }

             deleteAction.backgroundColor = UIColor(patternImage: newImage)
             return \[deleteAction\]
        }

enter image description here

1 Comment

Best answer ever!
2

trailingSwipeActionsConfigurationForRowAtIndexPath works from iOS 11 only and is completely not customizable. You can change background color of a button, but you cannot add an image with you own colors even if you use UIImageRenderingModeAlwaysOriginal.

I ended up using MGSwipeTableCell.

Comments

1

I was looking to do the same thing and found an answer here. It is a bit of a workaround.

Also, as seen from the iOS 9 betas, I think this will be possible, but I have not yet looked at the APIs.

1 Comment

thanks...i am checking with that answer now..i really appreciate your effort to put the answer on board..
0

If you use answer of "Apps Wise"(https://stackoverflow.com/a/32735211/6249148), you can use this table for common unicode characters: https://tutorialzine.com/2014/12/you-dont-need-icons-here-are-100-unicode-symbols-that-you-can-use

Or this one for ALL unicode characters: https://unicode-table.com/en/#control-character

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.