How to add image to row action in Table View?
Asked Answered
M

4

12

How to add custom image to delete button when swiping cell from right on UITableview as shown in the below image?

enter image description here

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

    let remove = UITableViewRowAction(style: .Default, title: "\nRemove") { action, indexPath in }
    remove.backgroundColor = UIColor(patternImage: UIImage(named: "remove")!) }

From the above code, Image is showing but, it is showing as a group of images stacked together. I mean, I am unable to set the "ContentMode" to ".ScaleToAspectFit" for the "UIImage"

What is the best way for this approach?

sample code could be appreciable.

Mannerly answered 7/4, 2016 at 9:32 Comment(2)
github.com/MortimerGoro/MGSwipeTableCell should be helpfulRidgway
Answered here -#44772278Disarmament
U
6

Inspired with Denny's answer. Here is objective-c version of his code.

- (NSArray *)tableView:(UITableView *)tableView editActionsForRowAtIndexPath:(NSIndexPath *)indexPath {

    UITableViewRowAction *deleteAction = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleDefault title:@"           " handler:^(UITableViewRowAction *action, NSIndexPath *indexPath)
    {
        UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Do you really want to delete this comment?" message:@"" delegate:self cancelButtonTitle:@"NO" otherButtonTitles:@"YES", nil];

        [alertView setTag:101];
        [alertView show];
    }];

    UITableViewCell *commentCell = (UITableViewCell *)[tableView cellForRowAtIndexPath:indexPath];

    CGFloat height = commentCell.frame.size.height;

    UIImage *backgroundImage = [self deleteImageForHeight:height];

    deleteAction.backgroundColor = [UIColor colorWithPatternImage:backgroundImage];

    return @[deleteAction];
}

And below is the image drawing method:

- (UIImage*)deleteImageForHeight:(CGFloat)height{

    CGRect frame = CGRectMake(0, 0, 62, height);

    UIGraphicsBeginImageContextWithOptions(CGSizeMake(62, height), NO, [UIScreen mainScreen].scale);

    CGContextRef context = UIGraphicsGetCurrentContext();

    CGContextSetFillColorWithColor(context, [UIColor redColor].CGColor);
    CGContextFillRect(context, frame);

    UIImage *image = [UIImage imageNamed:@"icon-delete"];

    [image drawInRect:CGRectMake(frame.size.width/2.0, frame.size.height/2.0 - 10, 18, 20)];

    UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();

    UIGraphicsEndImageContext();

    return newImage;
}

And the result is: Table view cell delete image

Urbanism answered 29/10, 2016 at 14:59 Comment(4)
Brilliant solution! I just want to mention, that title:@" " is important only for iOS < 11.0Kilgore
@VladE.Borovtsov I write this for iOS8 and not sure about latest version. Thank you for the updates.Urbanism
@Muzamill, it works fine even on iOS 12. On iOS 11 and iOS 12 the action buttons appears squared with title=nil or title=@"". But on lower version, to keep button squared and looking similar i had to insert title with 8 spaces.Kilgore
@VladE.Borovtsov Great Thanks!!Urbanism
T
5

Essentially, you are drawing in a context, then retrieve the new image from the context.

let label = UILabel(frame: CGRect(x: 0, y: 0, width: 80, height: 100))
label.text = "ADD"
label.textAlignment = .Center
label.textColor = UIColor.whiteColor()

let img: UIImage = UIImage(named: "delete")

UIGraphicsBeginImageContextWithOptions(imgSize, false, UIScreen.mainScreen().scale)
let context = UIGraphicsGetCurrentContext()

// Set background color
CGContextSetFillColorWithColor(context, UIColor.raangeRed().CGColor)
CGContextFillRect(context, CGRect(x: 0, y: 0, width: 80, height: 80))

// Draw image
img.drawInRect(CGRectMake(30, 15, 20, 20))

// Draw View
label.layer.renderInContext(context!)

// Retrieve new UIImage
let newImage: UIImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()

let deleteRowAction = UITableViewRowAction(style: .Normal, title: "           ") { (rowAction, indexPath) in
     // Do stuff   
    }
deleteRowAction.backgroundColor = UIColor(patternImage: newImage)

You can also create a custom view (with an UIImageView and UILabel) and render it inside the context.

Twofold answered 16/6, 2016 at 17:22 Comment(3)
Wow, great example! Thanks for showing how to use CGContext to draw label and apply background colour! Just what i neededBayly
Though the label seems slightly 'blurred' and does not give a nice visual. It would definitely work better if the image contains the text as well.Bayly
Exactly, depending also with your designer, if both of you can agree if the buttons will be dynamic or notTwofold
P
4

try this

let backImage = UIImageView(image: UIImage(named: "remove"))
backImage.contentMode = .scaleAspectFit
remove.backgroundColor = UIColor(patternImage:backImage.image!)

Choice-2

var img: UIImage = UIImage(named: "remove")
var imgSize: CGSize = tableView.frame.size
UIGraphicsBeginImageContext(imgSize)
img.drawInRect(CGRectMake(20, 0, 20, 20))
var newImage: UIImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
remove.backgroundColor = UIColor(patternImage: newImage)
Parallax answered 7/4, 2016 at 9:45 Comment(8)
Thanks Anbu. I've already tried first approach, but no use. Now, while trying second approach it is showing error Value of type "UITableViewRowAction" has no member "frame". I understood that we need to give the action's height and width.Mannerly
we cannot use tableView height, as it is much bigger than row right?Mannerly
@Mannerly - ok choice no 2 is works correct, if yes we go for next stepParallax
Choice 2 works, but with custom CGRectMake(20,0,20,20)Mannerly
@Mannerly -- happy to hear ,your problem is resolved or notParallax
One more thing, I cannot set the background custom color and cannot set multiple actions with image.Mannerly
Let us continue this discussion in chat.Mannerly
@ThreeCoins there is only image but no title text and no background color. how to achieve this all (image + text + background color)? swift 3Parlance
K
0

Swift 5 Xcode 11.3 Only Copy and Paste Code.....

func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {
    let deleteAction = UIContextualAction(style: .normal, title: "Delete") { (action, view, completion) in
        completion(true)
        print("Delete")
    }
    
    let muteAction = UIContextualAction(style: .normal, title: "Save") { (action, view, completion) in
        completion(true)
        print("Save")
    }
    
    deleteAction.image = UIImage(named: "dustbin")
    deleteAction.backgroundColor = UIColor.white
    
    muteAction.image = UIImage(named: "file")
    muteAction.backgroundColor = UIColor.white
    return UISwipeActionsConfiguration(actions: [deleteAction, muteAction])
}

enter image description here

Klemperer answered 30/9, 2020 at 5:53 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.