TrailingSwipeAction: How to deactivate auto delete on swipe through? - ios

I update my tablerowactions to the swift 4 equivalent to be able to set icons instead of text as the buttons that show when the user swipes left on a table-element. My problem is that the first defined action (in my case the delete action) automatically gets triggered if the users swipe through from right to left instead of just showing all available actions. I would like to deactivate this behaviour.
My code looks currently like this:
override func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {
let deleteAction = UIContextualAction(style: .normal, title: "", handler: { (ac:UIContextualAction, view:UIView, success:(Bool) -> Void) in
// implemantion of delete-button here
// ...
success(true)
})
deleteAction.image = #imageLiteral(resourceName: "deleteIcon")
deleteAction.backgroundColor = .red
return UISwipeActionsConfiguration(actions: [deleteAction])
}

UISwipeActionsConfiguration has a property that allows you to turn this behavior off, called performsFirstActionWithFullSwipe. (Documentation)
So instead of:
return UISwipeActionsConfiguration(actions: [deleteAction])
do something like this:
let configuration = UISwipeActionsConfiguration(actions: [deleteAction])
configuration.performsFirstActionWithFullSwipe = false
return configuration

Related

How do you hide other swipe cell actions when swiping the cell

I have a tableView with native SwipeCell functionality.
When users swipe the cell a little, I have two actions (delete & edit).
When you swipe the cell all the way, it will move the delete button (as expected), the problem is - the background is transparent, so when the delete button is over the edit icon it looks bad.
#available(iOS 11.0, *)
func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {
let deleteAction = UIContextualAction(style: .normal, title: nil) { [weak self] (action, view, complete) in
self?.deleteAction(tableView, at: indexPath)
complete(true)
}
if let cgImageX = #imageLiteral(resourceName: "alarmDelete").cgImage {
deleteAction.image = ImageWithoutRender(cgImage: cgImageX, scale: UIScreen.main.nativeScale, orientation: .up)
}
deleteAction.backgroundColor = UIColor.white.withAlphaComponent(0)
let editAction = UIContextualAction(style: .normal, title: nil) { [weak self] (action, view, complete) in
self?.editAction(tableView, at: indexPath)
complete(true)
}
if let editImage = #imageLiteral(resourceName: "edit").cgImage {
editAction.image = ImageWithoutRender(cgImage: editImage, scale: UIScreen.main.nativeScale, orientation: .up)
}
editAction.backgroundColor = UIColor.white.withAlphaComponent(0)
return UISwipeActionsConfiguration(actions: [deleteAction, editAction])
}
Is it possible to hide other actions when moving the cell all the way?
Video: https://i.imgur.com/9betbst.mp4
Thanks
You should update your code as follows to fix your issue.
let swipeActionConfig = UISwipeActionsConfiguration(actions: [deleteAction, editAction])
swipeActionConfig.performsFirstActionWithFullSwipe = false
return swipeActionConfig
But, this will prevent first action perform with full swipe, means you can't able to do first action when swipe cell to more after all action display.

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/

SwipeCellKit action won't perform segue

I'm using SwipeCellKit for my TO DO List app. When the user swipes left it deletes the item, but when the user swipes right I want him to be able to set a reminder on this item, so I've created an actionset a reminder
this action should perform a segue which brings the user to a custom popup with a date picker in it. The problem is that when I click on the button to set a reminder the simulator quits with an uncaught exception. I've already tried to perform deletion from this button it works perfectly, I've also tried to perform another segue to another view controller from this button the simulator quits. Could someone tell me what I'm doing wrong here? Here's my code:
func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath, for orientation: SwipeActionsOrientation) -> [SwipeAction]? { if orientation == .left {
guard isSwipeRightEnabled else { return nil }
let setReminder = SwipeAction(style: .default, title: "Set a reminder") { action, indexPath in
self.updateModelByAddingAReminder(at: indexPath)
}
setReminder.image = UIImage(named: "reminder-icon")
return[setReminder]
}else{
let deleteAction = SwipeAction(style: .destructive, title: "Delete") { action, indexPath in
self.updateModel(at: indexPath)
}
// customize the action appearance
deleteAction.image = UIImage(named: "delete-icon")
// return [setReminder, deleteAction]
return [deleteAction]
}
Ok, I found problem in your options for cell.
From doc
The built-in .destructive, and .destructiveAfterFill expansion styles are configured to automatically perform row deletion when the action handler is invoked (automatic fulfillment).
And you need use destructive style for cell in editActionsForRowAt. Or use another options, for example
func tableView(_ tableView: UITableView, editActionsOptionsForRowAt indexPath: IndexPath, for orientation: SwipeActionsOrientation) -> SwipeTableOptions {
var options = SwipeTableOptions()
options.transitionStyle = .border
if orientation == .left{
//or none
options.expansionStyle = .selection
}else{
options.expansionStyle = .destructive
}
return options
}
Hope it's help.

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.

Swipe actions for row with iOS system icons instead of text

I've set up a destructive trailing swipe action under iOS 11:
#available(iOS 11.0, *)
override func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {
let deleteAction = UIContextualAction(style: .destructive, title: "Delete", handler: { (action, view, completionHandler) in
self.deleteRow(atIndexPath: indexPath)
completionHandler(true)
})
// Is it possible here?
//deleteAction.image = UIImage(named: "delete")
let configuration = UISwipeActionsConfiguration(actions: [deleteAction])
return configuration
}
Instead of the "delete" text, I'd like to show the Apple system icon thrash bin found here:
https://developer.apple.com/ios/human-interface-guidelines/icons-and-images/system-icons/
Obviously, I could obtain the icon from somewhere and set it as the image, but I guess there should be a native way to do this.
Thanks for your suggestions!

Resources