How to disable swipe to delete option at UITableView - uitableview

I have 2 UITableView (Table-1 & Table-2) at same UIViewController. I want to editing functionality in my Table-2.
I have added tableview datasource method in my view controller as mentioned below: -
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
if editingStyle == .delete {
tableView.beginUpdates()
myArray.remove(at: indexPath.row)
tableView.deleteRows(at: [indexPath], with: .fade)
tableView.endUpdates()
}
}
and both tableview calling this method. So each tableview cells are able to open delete option.
But I want this delete editing option in only Table-2. I want to restrict delete editing option functionality in Table-1.
Please help. Thanks in advance.

You can use this function provided by UITableViewDelegate:
func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
return true
}
Simply implement some logic to check if you want to allow editing at the given indexPath and given tableView and return true if you want editing/deleting and return false if you don't.
Hope this helps!

Related

tableView(canEditRowAt) no longer working with tableViewDiffableDataSource

I created a fairly simple tableView for selecting a category for an item model. Everything was working fine yesterday. Today I have been trying to switch the tableView data source over to a UITableViewDiffableDataSource as I want to wrap my head around the API. I have the entire tableView back up and running EXCEPT I can no longer edit my rows!
the setEditing logic works as the newCategoryButton is disabled when I tap the edit button in the navigation bar and is enabled when I tap it again. However, I am never able to swipe to delete and the delete icons do not show up next to my rows in editing mode.
I tried removing setEditing, emptying out commit editingStyle and simply setting canEditRow to return true and still nothing.
Any help would be greatly appreciate. Thank!
override func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
let section = dataSource.snapshot().sectionIdentifiers[indexPath.section]
if section == .noneSelected {
return false
} else {
return true
}
}
override func setEditing(_ editing: Bool, animated: Bool) {
super.setEditing(editing, animated: true)
if editing == true {
newCategoryButton.isEnabled = false
} else {
newCategoryButton.isEnabled = true
}
}
override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
if editingStyle == .delete {
categories.remove(at: indexPath.row)
tableView.deleteRows(at: [indexPath], with: .automatic)
}
}
override func tableView(_ tableView: UITableView, canMoveRowAt indexPath: IndexPath) -> Bool {
return true
}
override func tableView(_ tableView: UITableView, moveRowAt sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath) {
let movedCategory = categories.remove(at: sourceIndexPath.row)
categories.insert(movedCategory, at: destinationIndexPath.row)
}
screenShot after edit button is tapped
The trouble is that canEditRowAt is a data source method. You (the view controller) are now not the data source; the diffable data source is. You need to implement this method inside the diffable data source. That's typically done by subclassing the diffable data source class, so that you can override this method. Otherwise, the diffable data source just returns its default value — which is false, which is why you currently can't edit any rows.

Remove Table View Cell from Table View with if statement

How do I remove a static table view cell by doing a if statement like this:
if ____ {
remove static cell
} else {
keep cell in tableview
}
The bolded part is what I need the code for. I searched the internet for an answer, but I could not find one. Thanks for the help! I'm using Swift 3
First, make sure to change cells to have Dynamic Properties, because static cells are hard-coded.
Second, you don't need an else statement. If the condition is true, delete the cell, otherwise do nothing. To delete a cell, use a function:
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
if editingStyle == .delete {
print("Cell deleted")
// delete any additional data from containers like arrays or dictionaries if needed
self.tableView.deleteRows(at: [indexPath], with: .automatic)
}
}
If this is a static tableview you can't remove a cell. If you attempt to you'll probably fall into all sorts of issues. Your best solution is to set the cell's height to zero and hide it.
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = super.tableView(tableView, cellForRowAt:indexPath)
if indexPath == cellToHide {
cell.isHidden = true
}
return cell
}
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
if indexPath == cellToHide {
return 0
}
return super.tableView(tableView, heightForRowAt: indexPath)
}

remove the delete button ⛔️ on table rows in edit mode

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;
}

using editActionsForRowAtIndexPath to delete a row "UITableView internal bug"

I need to create a action in editActionsForRowAtIndexPath to delete a row in a table. Following some research on the internet I came to this code:
func tableView(tableView: UITableView, editActionsForRowAtIndexPath indexPath: NSIndexPath) -> [UITableViewRowAction]? {
let remove = UITableViewRowAction(style: UITableViewRowActionStyle.Destructive, title: "Remover", handler: { (action: UITableViewRowAction, indexPath: NSIndexPath) -> Void in
self.tableData.removeObjectAtIndex(indexPath.row)
tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Automatic)
})
return [remove]
}
but now I get this error
UITableView internal bug: unable to generate a new section map with
old section count: 1 and new section count: 0
When you delete a row from UITableView, you need to take care of two things.
First you should call tableView.deleteRowsAtIndexPaths only after you remove the object from the data source already. Because it'll check for the count again and ensure that the resultant data source have one less value.
Now the second thing to remember is that the no. of section can't be 0 after you delete the last row. If you are returning 0 to numberOfSectionsInTableView, return 1 at least on empty row count. Another option is to actually delete the index too when you delete the last row.
You don't need to use 'editActionsForRowAtIndexPath' method unless you implement your own custom accessory view but other wise you can use the standard swipe left gesture to delete rows and the delegate called is commitEditingStyle
override func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
if editingStyle == .Delete {
tableData.removeObjectAtIndex(indexPath.row)
tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Automatic)
}
else if editingStyle == .Insert {
//edit cell
}
}
//change the default 'Delete' text
override func tableView(tableView: UITableView, titleForDeleteConfirmationButtonForRowAtIndexPath indexPath: NSIndexPath) -> String? {
return "Show this instead of delete"
}
Do deleteRowsAtIndexPaths or reloadData, but not both.

how to make a call when user swipe left in UITabelViewCell in iOS8 using swift

I am new to swift And programming. Please Anyone Help me for making call in IOS8 using UITabelViewCell left swipe not to delete A Row but to make a call in iPhone using Swift language
If you want to show a Delete or Insert button, you can use the following default functions of UITableView to accomplish that:
// Override to support conditional editing of the table view.
override func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool {
// Return NO if you do not want the specified item to be editable.
return true
}
// Override to support editing the table view.
override func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
if editingStyle == .Delete {
// Delete the row from the data source
tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Fade)
} else if editingStyle == .Insert {
// Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
}
}
Although if you want a different custom button, you should have a look at SWTableViewCell at this link: https://github.com/CEWendel/SWTableViewCell

Resources