I have a UITableView, which comes prefitted with an Edit button (UITableView.editButtonItem()). When pressed, it toggles to "Done", and you get those red minus signs next to entries for when you want to delete them.
I want to attach custom code to the button so that when you click it, you don't get the red minus signs. When in edit mode, whenever you click on an entry, it brings up a UIActionSheet or a UIAlertController to allow you to make the changes.
So, I want to override the Edit button so that when clicked:
The red minus "Delete" icons don't show up
The cells become selectable.
I've tried creating a custom UIBarButtonItem, but that's a terrible walkaround. I think what I want is do-able, I'm just not sure how.
Use delegate for UIViewController and make custom code on the events of that button. If it is on every row you must attach tap action from the code during cell generation.
I myself would preffer to have custom class.
I've figured out which methods to call:
// The following two functions remove the red minus sign
override func tableView(tableView: UITableView, editingStyleForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCellEditingStyle {
return UITableViewCellEditingStyle.None
}
override func tableView(tableView: UITableView, shouldIndentWhileEditingRowAtIndexPath indexPath: NSIndexPath) -> Bool {
return false
}
// The following property allows you to select cells while in editing mode
self.tableView.allowsSelectionDuringEditing = true
Related
I'm trying to implement two cells, one that can be deleted by swiping, and one that can't be deleted, but has swipe actions the other way.
This is what it looks like now:
I don't want the middle cell to be indented when clicking Edit.
Without any custom code, all cells would show this red circle and get a delete-button, but I have added a few lines of code to prevent that.
This code will set all cells without a leading or trailing swipe action to not become editable, which explains the bottom cell in the gif. I have to include the leading swipe actions to this, because if the cell isn't editable, then I can't swipe at all.
func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
let vm = sections[indexPath.section].viewModels[indexPath.row]
return vm.leadingSwipeActions != nil || vm.trailingSwipeActions != nil
}
The following code will prevent the middle cell from showing the red circle.
func tableView(_ tableView: UITableView, editingStyleForRowAt indexPath: IndexPath) -> UITableViewCell.EditingStyle {
return sections[indexPath.section].viewModels[indexPath.row].trailingSwipeActions == nil ? .none : .delete
}
If I don't pass .none for the cell with leading actions, then it would show the red circle AND it would even show a default deletion-swipe. I don't want the ability to delete this row!
How can I prevent the middle cell from indenting, while still retaining the ability to swipe it?
This method seems to work! tableView(_ tableView: UITableView, shouldIndentWhileEditingRowAt indexPath: IndexPath) -> Bool
https://developer.apple.com/documentation/uikit/uitableviewdelegate/1614873-tableview?language=objc
I want to customise the delete indicator for a UITableView in editing mode.
Since I can't seem to find a way to customise the appearance style of the delete button shown in the first image, I've created my own animation with my own button.
I have deactivated the red standard button using:
func tableView(_ tableView: UITableView, editingStyleForRowAt indexPath: IndexPath) -> UITableViewCellEditingStyle {
return .none
}
Now my question: How do I realize the same behaviour as the standard button? If you press the red button, it invokes a swipe left on the cell showing the wanted delete button.
Help is very appreciated.
I have a custom table view cell that has a toggle button on the left side.
When the tableview's isEditing property is set to true, the delete editing option appears properly, but when it's tapped, nothing happens.
The stranger thing is, when I tap and hold, and then drag to one side away from the button, and THEN lift, the cell finally slides over. Which isn't how it's supposed to work at all.
Even when I remove connections to the toggle button from the storyboard and the subclass, it still behaves this way.
Why is it doing this?
First of all, correct me if I'm wrong, but I think these are two different problems.
1.Nothing happens when the "delete editing" button is tapped. I would check if the "delete editing" button properly connected to the class file with an IBAction.
2.The cell slide behavior is not what is desired. I would check to see if the gesture you're recognizing is a tap and not a left swipe.
Hope that helps.
you need to add following methods in your table view controller
func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
return true
}
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
if (editingStyle == UITableViewCellEditingStyle.delete) {
//remove element from your array providing index.row
tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Fade)
)
}
}
In my storyboard, I have a UITableViewController (embedded in a UINavigationController) on which I have added a CANCEL button as a Left Bar Button Item.
At runtime, the CANCEL button doesn't appear, but an EDIT button does.
I haven't explicitly added the EDIT button and have kept the default implementation of the edit function in its disabled state thus:
// Override to support conditional editing of the table view.
override func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
// Return false if you do not want the specified item to be editable.
return false
}
I've looked into ways to hide the EDIT button and this line of code works:
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
self.navigationItem.leftBarButtonItem = nil
}
... in that it hides the EDIT button. But, it also hides the CANCEL and all other buttons on the left!
I have discovered code that explicitly shows the EDIT button, i.e.:
self.navigationItem.leftBarButtonItem = self.editButtonItem
But cannot find an equivalent for CANCEL.
So, is there a way to hide the EDIT button but show the CANCEL button?
--- UPDATE #1 ---
I have already connected the Cancel button to my class code via an IBOutlet per attached screenshot.
--- UPDATE #2 ---
I have now ensured that
tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath)
and
tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath)
are commented out. So, as far as I can tell, there is nothing about this TableViewController that enables editing of rows. Yet, the 'EDIT' button still appears and obfuscates my 'CANCEL' button.
leftBarButtonItems is a slightly different thing than leftBarButtonItem
It sounds like your cancel button has been added to the leftBarButtonItems of the navigationItem for your view controller, but you don't have a reference to it in your class. Create an IBOutlet reference for it and you should be able to set it explicitly as the leftBarButtonItem in the same way as you are the edit button.
Facepalm time.
I had copied over a method from another class which had the edit button explicitly displayed the following line:
self.navigationItem.leftBarButtonItem = self.editButtonItem
Deleting this line removes the EDIT button at run time.
I have a UITableView that has multi selection enabled. I have been using the "selection" to actually change the height of the rows, showing extra detail when "selected". E.g.
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
self.tableView.beginUpdates()
self.tableView.endUpdates()
}
func tableView(tableView: UITableView, didDeselectRowAtIndexPath indexPath: NSIndexPath) {
self.tableView.beginUpdates()
self.tableView.endUpdates()
}
func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
return (self.tableView.indexPathsForSelectedRows?.contains(indexPath) ?? false) ? 200 : 92
}
This seems to work pretty well. Until I start doing any swipes actions. When I add some swipe actions, the swipe action seems to clear all of my selections. I actually wanted to deselect the one I was swiping, so it would shrink back down. But the clearing of all my selections doesn't seem to trigger any of the normal delegate callbacks. Even though I have allowsMultipleSelectionDuringEditing set to true.
Is there a way to do this? Should I skip (ab)using the selection state as a way to indicate whether the row is showing details with a different height or not? Or is there a way to use it in conjunction with the behavior of the swipes being done in "edit mode" and clearing all of my selections?
The best way is using NSArray to store indexPath of selected cells, and base on saved indexPath you can check and do anything you want. another bug may happened in your code is: What happened in the case user make scroll on tableview? Does cell will reuse and lose select state? New cell reuse the old cell with 200 height will has wrong height?