custom delete image within UITabelViewCell only show half of itself - ios

I want to custom my delete button of the UITableViewCell like these codes:
let deleteAciont = UITableViewRowAction(style: UITableViewRowActionStyle.Normal, title: nil, handler: {action, indexpath in
do some thing
});
deleteAciont.backgroundColor = UIColor(patternImage: UIImage(named: "delete")!)
the height of the UITableViewCell is 70 like this:
override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
return 70
}
and the images are these size: delete.png:70*70\delete#2x.png:140*140\delete#3x.png:210*210
but when i swipe left, the image only show half:
I have been confusing about this for a long time and thanks for your help

the length of the tableViewRowAction will be the title's length
let deleteAciont = UITableViewRowAction(style: UITableViewRowActionStyle.Normal, title: " type more space here ", handler: {action, indexpath in
do some thing
});

Related

Swift: Swipe action to strikethrough row in TableView

Evening ladies and gentleman,
I am currently getting used to Swift and wanted to start with a little todo app. So far I can add an item and safe it persistently in a context. When an item has been added, it will be shown in a tableview. Now, I want to use a check swipe to strikethrough items, which have been added and safe this information in my context. Deleting using a swipe works perfectly fine.
Has anybody an idea how realize this? I tried to solve it by myself, but couldnt get it done. A similar question has been asked here before, but didnt get a proper answer: Add strikethrough to tableview row with a swipe
func checkAccessoryType(cell: UITableViewCell, isCompleted: Bool) {
if isCompleted {
cell.accessoryType = .checkmark
} else {
cell.accessoryType = .none
}
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let todo = CoreDataManager.shared.getTodoItem(index: indexPath.row)
todo.completed = !todo.completed
CoreDataManager.shared.safeContext()
if let cell = tableView.cellForRow(at: indexPath){
checkAccessoryType(cell: cell, isCompleted: todo.completed)
}
}
Assuming you are trying to strikethrough the title of your task -- which should be defined as a label -- here is the approach to take:
1- Make sure your label is set to attributed text rather than plain. To do that, go to Main.storyboard, select your label, and inside the attribute inspector, set text to Attributed.
2- Inside your completion block (that is the completion block executed after a swipe) add the following code:
(SWIFT 5)
let attributeString: NSMutableAttributedString = NSMutableAttributedString(string: taskLabel.text)
attributeString.addAttribute(.strikethroughStyle, value: 1, range: NSRange(location: 0, length: taskLabel.text.count))
taskLabel.attributedText = attributeString
Just a little advice: it's always helpful if you add some code when you ask a question.
Let me know if anything doesn't make sense.
Looking at the link that you provided, you need swipe action on your UITableViewCell.
Try looking into:
leadingSwipeActionsConfigurationForRowAt
trailingSwipeActionsConfigurationForRowAt
You need this action to perform the strikethrough label or delete:
func tableView(_ tableView: UITableView,
leadingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration?
{
let closeAction = UIContextualAction(style: .normal, title: "Close", handler: { (ac:UIContextualAction, view:UIView, success:(Bool) -> Void) in
print("OK, marked as Closed")
success(true)
})
closeAction.image = UIImage(named: "tick")
closeAction.backgroundColor = .purple
return UISwipeActionsConfiguration(actions: [closeAction])
}
func tableView(_ tableView: UITableView,
trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration?
{
let modifyAction = UIContextualAction(style: .normal, title: "Update", handler: { (ac:UIContextualAction, view:UIView, success:(Bool) -> Void) in
print("Update action ...")
success(true)
})
modifyAction.image = UIImage(named: "hammer")
modifyAction.backgroundColor = .blue
return UISwipeActionsConfiguration(actions: [modifyAction])
}
Source: https://developerslogblog.wordpress.com/2017/06/28/ios-11-swipe-leftright-in-uitableviewcell/

UITableView multiple actions

In the editing mode of UITableView, I need three things, the first two are easy to get using UITableView delegate methods:
Delete (- in red) button on the left of the row,
Reorder (three bars) row button on the right of the row,
A custom defined action (with title & background color) appearing on the left side of reorder (three bars) button.
How is it possible to get these three actions together?
Hi yes it is possible to make or add your own custom action by implementing the tableView delegate
func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]? {
let archiveAction:UITableViewRowAction = UITableViewRowAction(style: .default, title: " ") { (rowAct, index) in
}
let deleteAction:UITableViewRowAction = UITableViewRowAction(style: .default, title: " ") { (rowAct, index) in
}
let archiveImg = UIImageView(image: UIImage(named: "archive_btn"))
archiveImg.contentMode = .scaleAspectFit
archiveAction.backgroundColor = UIColor(patternImage:archiveImg.image!)
let deleteImg = UIImageView(image: UIImage(named: "delete_btn"))
deleteImg.contentMode = .scaleAspectFit
deleteAction.backgroundColor = UIColor(patternImage:deleteImg.image!)
return [deleteAction,archiveAction]
}

How can add image in UIContextualAction in UITableview DataSource method

i am trying to add image in the UIContextualAction , see the code below:-
func tableView(_ tableView: UITableView,
trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration?
{
// Write action code for the Flag
let FlagAction = UIContextualAction(style: .normal, title: "View", handler: { (ac:UIContextualAction, view:UIView, success:(Bool) -> Void) in
print("Update action ...")
success(true)
})
FlagAction.image = UIImage(named: "flag")
return UISwipeActionsConfiguration(actions: [FlagAction])
}
The image , i am using
we can take size 30 by 30 , is the standard size , we can take more than 30 pixel , depending on the size of the screen.
Here is the image that is support
The UIContextualAction only accepts template image, which use different transparent degree to define the image's shape and color.
hi it is worked fine for me ,
That image size will auto adjust according to pixel of the image.
private func searchBarCode(forRowAt indexPath: IndexPath) -> UIContextualAction {
let context = UIContextualAction(style: .destructive, title: "") { (action, swipeButtonView, completion) in
completion(true)
}
context.backgroundColor = UIColor.white
context.image = UIImage(named: "document")
return context
}
Click here to see table view edit image

swift swipe tableview cell set image with trailingSwipeActionsConfigurationForRowAt AND editActionsForRowAt

swipe table view cell then show some option to delete and edit. I want to set full image. I have seen lots of demo code but then are with text and background image, I have need to create with whole image here is my code for ios 10 and ios 11 but I cant get success
with editActionsForRowAt Problem is image is repeate multiple time
func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]?
{
let ArchiveAction = UITableViewRowAction(style: UITableViewRowActionStyle.default, title: " ") { (action , indexPath ) -> Void in
tableView.setEditing(false, animated: false)
}
let shareAction = UITableViewRowAction(style: UITableViewRowActionStyle.default, title: " ") { (action , indexPath) -> Void in
tableView.setEditing(false, animated: false)
}
ArchiveAction.backgroundColor = UIColor(patternImage: UIImage(named: "archiver.png")!)
shareAction.backgroundColor = UIColor(patternImage: UIImage(named: "bloquear.png")!)
return [ArchiveAction,shareAction]
}
with trailingSwipeActionsConfigurationForRowAt Problem is image not show properly. show white image
#available(iOS 11.0, *)
func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {
let action = UIContextualAction(style: .normal, title: "sdfsdf", handler: { (action,view,completionHandler ) in
//do stuff
completionHandler(true)
})
// action.image = UIImage(named: "archiver.png")
action.backgroundColor = .black
let confrigation = UISwipeActionsConfiguration(actions: [action])
confrigation.performsFirstActionWithFullSwipe = true // default is false
return confrigation
}
Please give me any solution
I also experienced the problem of a white rectangle instead of the image when using .jpg. Using a .png worked for me.
Since you are using a .png already, did you try to load the image name without the .png extension? ("archiver" instead of "archiver.png")
Because the parameter description of init?(named name: String) says:
... For PNG images, you may omit the filename extension. For all other file formats, always include the filename extension.

How to add image in UITableViewRowAction?

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?
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
}
WWDC video at 28.34
Apple Doc
Note: I have used 50*50 points apple.png image with 50 tableview row height
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]
}
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:
add pod
import SwipeCellKit
make cell conform to SwipeTableViewCell
in cellForRow function set the cells delegate to self
follow the implementation below or via the link
link 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
}
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
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];
}
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

Resources