How to add image to UITableViewRowAction?

I am trying to add an image to the UITableView Swipe style. I tried with text Emoji and its working fine

 func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]? { let editAction = UITableViewRowAction(style: .normal, title: "🖋") { (rowAction, indexPath) in print("edit clicked") } return [editAction] } 

But I need an image instead of Emoji, meanwhile I tried

 editAction.backgroundColor = UIColor.init(patternImage: UIImage(named: "edit")!) 

But he received a duplicate image, I used images in many formats, for example, 20 * 20, 25 * 25, 50 * 50, but still repeated.

How to add an image?

+9
ios uitableview swift
Jun 27 '17 at 3:21
source share
6 answers

Finally, in iOS 11 , SWIFT 4, we can add an image to a UITableView action using a UISwipeActionsConfiguration

 @available(iOS 11.0, *) func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? { let action = UIContextualAction(style: .normal, title: "Files", handler: { (action,view,completionHandler ) in //do stuff completionHandler(true) }) action.image = UIImage(named: "apple.png") action.backgroundColor = .red let confrigation = UISwipeActionsConfiguration(actions: [action]) return confrigation } 

WWDC video at 28.34

Apple doc

Note. I used 50 * 50 dots of apple.png image with 50 tableview row height

+20
09 Oct '17 at 13:23
source share
— -

I had the same problem with my project, so I made a workaround for this. I think this is good for you.

When I look at the table cell on the left just for the width of the image, it works fine.

enter image description here

But when I scroll the table cell more than the width of the image, the display of the table cell looks like this:

enter image description here

This is because I use the backgroundColor property to add an image.

 copyButton.backgroundColor = UIColor(patternImage: UIImage(named: "bfaCopyIcon.png")!) 

So, to fix this, I am increasing the width of the image as well as the width of the table.

old image → → → → → → new image

enter image description here →> enter image description here

this is a new view:

enter image description here

This is my sample code:

 func tableView(_ tableView: UITableView, editActionsForRowAt: IndexPath) -> [UITableViewRowAction]? { let copyButton = UITableViewRowAction(style: .normal, title: "") { action, index in print("copy button tapped") } copyButton.backgroundColor = UIColor(patternImage: UIImage(named: "bfaCopyIcon.png")!) let accessButton = UITableViewRowAction(style: .normal, title: "") { action, index in print("Access button tapped") } accessButton.backgroundColor = UIColor(patternImage: UIImage(named: "bfaAccess.png")!) return [accessButton, copyButton] } 
+4
Mar 22 '18 at 7:26
source share

I found one way to do this in SWIFT 3 -

enter image description here

  func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]? { //let cell = tableView.cellForRow(at: indexPath) //print(cell?.frame.size.height ?? 0.0)//hence we need this height of image in points. make sure your contentview of image is smaller let deleteAction = UITableViewRowAction(style: .normal, title:" ") { (rowAction, indexPath) in print("delete clicked") } deleteAction.backgroundColor = UIColor(patternImage:UIImage(named: "delete")!) return [deleteAction] } 

We need to make sure that the image size matches the row height of the cell. Here is my image that I used enter image description here

+1
Jul 25 '17 at 10:56 on
source share

I ran into the same problem and discovered a really good module for this, called SwipeCellKit , which makes it really easy to embed an image in the action of your swipe cell without the swipe action resulting in multiple images being displayed. it also allows for more customization, such as different directions of impact.

Stages:

  1. add pod
  2. import SwipeCellKit
  3. align cell to SwipeTableViewCell
  4. in the cellForRow function cellForRow set the cell delegate to yourself
  5. follow the implementation below or follow the link

module link → https://github.com/SwipeCellKit/SwipeCellKit

 func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath, for orientation: SwipeActionsOrientation) -> [SwipeAction]? { guard orientation == .right else { return nil } let deleteAction = SwipeAction(style: .destructive, title: "Delete") { action, indexPath in // handle action by updating model with deletion } // customize the action appearance deleteAction.image = UIImage(named: "delete") return [deleteAction] } func tableView(_ tableView: UITableView, editActionsOptionsForRowAt indexPath: IndexPath, for orientation: SwipeActionsOrientation) -> SwipeOptions { var options = SwipeOptions() options.expansionStyle = .destructive return options } 
+1
Oct. 15 '18 at 5:28
source share

This is how I do it in objective-c and should work in swift when translating.

 - (NSArray<UITableViewRowAction *> *)tableView:(UITableView *)tableView editActionsForRowAtIndexPath:(NSIndexPath *)indexPath{ NSString *deleteString = @"Delete"; CGFloat tableViewCellHeight = [self tableView:tableView heightForRowAtIndexPath:indexPath]; UIImage *image = [UIImage imageNamed:@"delete_icon"]; CGFloat fittingMultiplier = 0.4f; CGFloat iOS8PlusFontSize = 18.0f; CGFloat underImageFontSize = 13.0f; CGFloat marginHorizontaliOS8Plus = 15.0f; CGFloat marginVerticalBetweenTextAndImage = 3.0f; float titleMultiplier = fittingMultiplier; NSString *titleSpaceString= [@"" stringByPaddingToLength:[deleteString length]*titleMultiplier withString:@"\u3000" startingAtIndex:0]; UITableViewRowAction *rowAction= [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleDefault title:titleSpaceString handler:^(UITableViewRowAction *action, NSIndexPath *indexPath){ //Do Stuff }]; CGSize frameGuess=CGSizeMake((marginHorizontaliOS8Plus*2)+[titleSpaceString boundingRectWithSize:CGSizeMake(MAXFLOAT, tableViewCellHeight) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{ NSFontAttributeName: [UIFont systemFontOfSize:iOS8PlusFontSize] } context:nil].size.width, tableViewCellHeight); CGSize tripleFrame=CGSizeMake(frameGuess.width*3.0f, frameGuess.height*3.0f); UIGraphicsBeginImageContextWithOptions(tripleFrame, YES, [[UIScreen mainScreen] scale]); CGContextRef context=UIGraphicsGetCurrentContext(); [[UIColor blueColor] set]; CGContextFillRect(context, CGRectMake(0, 0, tripleFrame.width, tripleFrame.height)); CGSize drawnTextSize=[deleteString boundingRectWithSize:CGSizeMake(MAXFLOAT, tableViewCellHeight) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{ NSFontAttributeName: [UIFont systemFontOfSize:underImageFontSize] } context:nil].size; [image drawAtPoint:CGPointMake((frameGuess.width/2.0f)-([image size].width/2.0f), (frameGuess.height/2.0f)-[image size].height-(marginVerticalBetweenTextAndImage/2.0f)+2.0f)]; [deleteString drawInRect:CGRectMake(((frameGuess.width/2.0f)-(drawnTextSize.width/2.0f))*([[UIApplication sharedApplication] userInterfaceLayoutDirection]==UIUserInterfaceLayoutDirectionRightToLeft ? -1 : 1), (frameGuess.height/2.0f)+(marginVerticalBetweenTextAndImage/2.0f)+2.0f, frameGuess.width, frameGuess.height) withAttributes:@{ NSFontAttributeName: [UIFont systemFontOfSize:underImageFontSize], NSForegroundColorAttributeName: [UIColor whiteColor] }]; [rowAction setBackgroundColor:[UIColor colorWithPatternImage:UIGraphicsGetImageFromCurrentImageContext()]]; UIGraphicsEndImageContext(); return @[rowAction]; } MAXFLOAT, tableViewCellHeight) options: NSStringDrawingUsesLineFragmentOrigin attributes: @ {NSFontAttributeName: [UIFont systemFontOfSize: iOS8PlusFontSize]} context: nil] .size.width, tableViewCellHeight); - (NSArray<UITableViewRowAction *> *)tableView:(UITableView *)tableView editActionsForRowAtIndexPath:(NSIndexPath *)indexPath{ NSString *deleteString = @"Delete"; CGFloat tableViewCellHeight = [self tableView:tableView heightForRowAtIndexPath:indexPath]; UIImage *image = [UIImage imageNamed:@"delete_icon"]; CGFloat fittingMultiplier = 0.4f; CGFloat iOS8PlusFontSize = 18.0f; CGFloat underImageFontSize = 13.0f; CGFloat marginHorizontaliOS8Plus = 15.0f; CGFloat marginVerticalBetweenTextAndImage = 3.0f; float titleMultiplier = fittingMultiplier; NSString *titleSpaceString= [@"" stringByPaddingToLength:[deleteString length]*titleMultiplier withString:@"\u3000" startingAtIndex:0]; UITableViewRowAction *rowAction= [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleDefault title:titleSpaceString handler:^(UITableViewRowAction *action, NSIndexPath *indexPath){ //Do Stuff }]; CGSize frameGuess=CGSizeMake((marginHorizontaliOS8Plus*2)+[titleSpaceString boundingRectWithSize:CGSizeMake(MAXFLOAT, tableViewCellHeight) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{ NSFontAttributeName: [UIFont systemFontOfSize:iOS8PlusFontSize] } context:nil].size.width, tableViewCellHeight); CGSize tripleFrame=CGSizeMake(frameGuess.width*3.0f, frameGuess.height*3.0f); UIGraphicsBeginImageContextWithOptions(tripleFrame, YES, [[UIScreen mainScreen] scale]); CGContextRef context=UIGraphicsGetCurrentContext(); [[UIColor blueColor] set]; CGContextFillRect(context, CGRectMake(0, 0, tripleFrame.width, tripleFrame.height)); CGSize drawnTextSize=[deleteString boundingRectWithSize:CGSizeMake(MAXFLOAT, tableViewCellHeight) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{ NSFontAttributeName: [UIFont systemFontOfSize:underImageFontSize] } context:nil].size; [image drawAtPoint:CGPointMake((frameGuess.width/2.0f)-([image size].width/2.0f), (frameGuess.height/2.0f)-[image size].height-(marginVerticalBetweenTextAndImage/2.0f)+2.0f)]; [deleteString drawInRect:CGRectMake(((frameGuess.width/2.0f)-(drawnTextSize.width/2.0f))*([[UIApplication sharedApplication] userInterfaceLayoutDirection]==UIUserInterfaceLayoutDirectionRightToLeft ? -1 : 1), (frameGuess.height/2.0f)+(marginVerticalBetweenTextAndImage/2.0f)+2.0f, frameGuess.width, frameGuess.height) withAttributes:@{ NSFontAttributeName: [UIFont systemFontOfSize:underImageFontSize], NSForegroundColorAttributeName: [UIColor whiteColor] }]; [rowAction setBackgroundColor:[UIColor colorWithPatternImage:UIGraphicsGetImageFromCurrentImageContext()]]; UIGraphicsEndImageContext(); return @[rowAction]; } 
0
Jun 29 '17 at 1:00
source share
 func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]? { let write = UITableViewRowAction(style: .default, title: "\u{1F58A}") { action, index in print("edit button tapped") } return [write] } 

try using the unicode icon instead of the icon. it will work

-2
Jun 28 '17 at 6:33
source share



All Articles