I have a UITableViewCell where I have implemented leadingSwipeActionsConfigurationForRowAt indexPath to allow users to drag right on cells to add them to their favorites. However, in doing so the option for dragging left to delete also appeared. I don't want these cells to be able to be deleted. Is there a way to implement swipe actions without the delete action appearing?
Try this
func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
return false
}
Edit
func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {
let swipeAction = UISwipeActionsConfiguration(actions: [])
swipeAction.performsFirstActionWithFullSwipe = false // This is the line which disables full swipe
return swipeAction
}
Related
I have implemented iOS 11 trailingSwipeActionsConfigurationForRowAt and leadingSwipeActionsConfigurationForRowAt for my UITableViewCell. I'm using trailingSwipeActionsConfigurationForRowAt to disable the row, and leadingSwipeActionsConfigurationForRowAt to undo the disable of the row. I've tried to use canEditRowAt, but this disables editing of the entire row. Is there a way to disable only one of the swipe actions instead of disabling the entire row from editing?
I want to disable the undo swipe action if I already swiped to undo, but enable the cancel swipe action. I also want to disable the cancel swipe action if I already swiped to cancel, but enable the undo swipe action.
Try to return the empty array of actions in trailingSwipeActionsConfigurationForRowAt method to disable one sided action.
func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {
let swipeAction = UISwipeActionsConfiguration(actions: [])
return swipeAction
}
Returning nil is sufficient to prevent the swipe action.
func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {
return nil
}
When I click on Edit button in my screen i change my TableView to edit mode and set the edit style as check box by doing this
func tableView(_ tableView: UITableView, editingStyleForRowAt indexPath: IndexPath) -> UITableViewCellEditingStyle {
return UITableViewCellEditingStyle.init(rawValue: 3)!
}
now I need programatically pre check some of the entries.
How can i Make some of the cells as checked?
I know in
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
I have to set the edit style which marks it as checked.
I finally figured it out.
Setting the Checkbox in an table view is equivalent to selecting the cell.
so all you need to do is mark the sell as selected, nothing to do with the Edit style
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "MyCell", for: indexPath) as! MyCell
let item = self.items[indexPath.row]
cell.setup(item: item)
cell.setSelected(true, animated: true) // Provided your cell is already in check box edit mode, then this makes it CHECK ON
return cell
}
By the way. I saw an explanation in similar question here (on SO) that you should not use this:
return UITableViewCellEditingStyle.init(rawValue: 3)!
Because it's not public API and if Apple changes this value, application will stop working properly. The same behaviour can be reached simply by enabling Multiple selection during editing:
You can check it easily by setting breakpoint on your overridden method
func tableView(_ tableView: UITableView, editingStyleForRowAt indexPath: IndexPath) -> UITableViewCellEditingStyle {
return UITableViewCellEditingStyle.init(rawValue: 3)!
}
And enable editing during running the app with Multiple selection during editing and without it. You will see that if Multiple selection during editing is enabled, this method will not be called at all.
I've been using editActionsForRowAt to create the built-in swipe left functionality to reveal quick-access buttons, like this:
func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]? {
print("Is this working?")
//Code to create UITableViewRowAction buttons
return [button1, button2]
}
func tableView (_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
//I read I need this, so I have it
return true
}
func tableView (_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
//I read I need this, so I have it
}
Now my whole table, including the swipe, works great. Until...
My editActionsForRowAt function has code where if the user swipes a cell that's expanded (by default they're 50, but users can tap to expand the height) then editActionsForRowAt returns [], an empty array. I do that because I don't want really tall cells showing stretched out buttons.
After that, even after closing, swiping a cell (any cell) doesn't even call editActionsForRowAt. I checked by adding a print-line right at the beginning of that function and it doesn't print no matter what I do after swiping an expanded cell and returning [].
Any ideas on how to fix this?
Instead of returning an empty array from editActionsForRowAt, you should return false from canEditRowAt when a given row isn't editable.
I am trying to learn Swift, but there is a problem in my project that drives me nuts.
I have a working list of data in a ViewController fed by parse.com. I managed to implement a swipe-feature that reveals buttons for both deleting and editing. That is working fine. Now I want the user to be able to reorder the cells. So I successfully implemented a button to put the table into editing-mode. My 2 problems with that are:
When I enter edit-mode I just want to be able to reorder the cells since editing and deleting is done via swipe (via "tableView(tableView: UITableView, editActionsForRowAtIndexPath indexPath: NSIndexPath)". How can I achive that the user doesn't see the 2 buttons for deleting and editing when in editing-mode and touching the delete-circle that is provided automatically?
Is it possible to remove the delete-circle altogether? Using "UITableViewCellEditingStyle.None" also disables the swipe-functionality.
Thanks in advance!
To avoid the round red delete button that appears when you put set UITableView isEditing to true at the left and does nothing when you click it, the minimum that worked for me was this (Swift 4, iOS 11)
// Avoid the round red delete button on the left of the cell:
func tableView(_ tableView: UITableView, shouldIndentWhileEditingRowAt indexPath: IndexPath) -> Bool {
return false
}
func tableView(_ tableView: UITableView, editingStyleForRowAt indexPath: IndexPath) -> UITableViewCellEditingStyle {
return .none
}
I also have these functions, which probably interact:
func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
return savedTempTable.isEditing
}
// Including this function in the delegate enable left-swipe deleting
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath)
{
if editingStyle == .delete {
savedConversions.remove(at: indexPath.row)
}
}
// Including this function enables reordering
func tableView(_ tableView: UITableView, moveRowAt sourceIndexPath: IndexPath,to destinationIndexPath: IndexPath)
{
let elem = savedConversions.remove(at: sourceIndexPath.row)
savedConversions.insert(elem, at: destinationIndexPath.row)
}
override func tableView(_ tableView: UITableView, editingStyleForRowAt indexPath: IndexPath) -> UITableViewCellEditingStyle {
return .none
}
override func tableView(_ tableView: UITableView, shouldIndentWhileEditingRowAt indexPath: IndexPath) -> Bool {
return false
}
Although people can delete a row through swipe the delete-button in editing mode should not be removed. People may not know about the swipe gesture and by removing the delete button (which they already expect in editing mode) the app becomes more difficult to use.
If you really want to remove the delete button then you have to implement the delegate method tableView(_:editingStyleForRowAtIndexPath:). There you can return .None while the screen is in editing mode and .Delete while the screen is not.
To enable reordering you have to implement the data source methods tableView(_:canMoveRowAtIndexPath:) and tableView(_:moveRowAtIndexPath:toIndexPath:).
You follow this way to remove the delete Icon while editing:
-(UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath{
return UITableViewCellAccessoryNone;
}
Some rows in my UITableView needs to delete and move in edit mode, but some just move.
In this method I can enable or disable editing for some rows
override func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool{
return true
}
But how to disable delete for some rows with enabled move?
Return .None for editingStyleForRowAtIndexPath:
func tableView(tableView: UITableView, editingStyleForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCellEditingStyle {
return .None
}
A more complete answer that displays how to remove indentions is here -> Is there any way to hide "-" (Delete) button while editing UITableView