Reputation: 14329
I'm trying to add image in UITableView
Swipe style. I tried with Emoji text & 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 image instead of Emoji, meanwhile I tried
editAction.backgroundColor = UIColor.init(patternImage: UIImage(named: "edit")!)
But it's getting duplicate image, I used images in many format like 20*20, 25*25, 50*50 but still duplicating.
How can I add image?
Upvotes: 15
Views: 17001
Reputation: 14329
Finally in iOS 11, SWIFT 4 We can add add image in UITableView's swipe action with help of 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 configuration = UISwipeActionsConfiguration(actions: [action])
return configuration
}
Note: I have used 50*50 points apple.png image with 50 tableview
row height
Upvotes: 28
Reputation: 589
I came across this same problem and discovered a really good pod for this called SwipeCellKit
that makes it really easy to implement an image into your swipe cell action without the swipe action causing multiple images to show. it also allows for more customization such as different swipe directions.
Steps:
import SwipeCellKit
SwipeTableViewCell
cellForRow
function set the cells delegate to selflink to pod -> 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
}
Upvotes: 3
Reputation: 488
I had the same problem with my project, so I did a workaround for this. I think, this is helpful for you.
When I swipe table cell to the left only for image width, it is working fine.
But when I swipe table cell more than image width, table cell display like this:
This happen because to add image I use 'backgroundColor' property.
copyButton.backgroundColor = UIColor(patternImage: UIImage(named: "bfaCopyIcon.png")!)
So to fix this, I increase image width to the same as table width.
old image >>>>>>>>>>>> new image
this is the new look:
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]
}
Upvotes: 6
Reputation: 14329
I found one way of doing this in SWIFT 3 -
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 our image dimension is matching with cell row height
Here is my image which i used
Upvotes: 1
Reputation: 826
Here is how I do it in objective-c
and should work in swift
when translated.
- (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];
}
Upvotes: 0
Reputation: 159
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 this used unicode instead icon. this will work
Upvotes: -2