How to select another row right after deleting row in tableView (Swift) - ios

I am deleting row and want to get next behavior:
If I am deleting row that was selected, I need to get another row selected automatically.
And also if I have an additional trouble, when I am perform deleting, target row that is going to be deleted selecting automatically, I don't need it to be selected as I want to only delete it.
The main question is 1 for now.
I understand that maybe row: 0 does not exists anymore but t's not a point now, I just simplified code to make it more comfortable to discuss the point. I tried performBatchUpdates, and tried to move selectRow(at:section:) to completion closure as well, row selection not works too.
selectRow works perfectly after insertRows function, so I am confused.
override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
if editingStyle == .delete {
tableView.beginUpdates()
tableView.deleteRows(at: [indexPath], with: .fade)
tableView.endUpdates()
tableView.selectRow(at: IndexPath(row: 0, section: 0), animated: false, scrollPosition: .middle)
}
}

As I understood your question, find this solution:
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
if editingStyle == .delete {
tableView.beginUpdates()
tableView.deleteRows(at: [indexPath], with: .fade)
tableView.endUpdates()
tableView.selectRow(at: indexPath, animated: true, scrollPosition: .none)
}
}
Pass indexPath while deleting a row and after endUpdates, you just need to set the same indexPath as SelectedRow.

Ok, I've found solution for the 1st question (just thought maybe such function can exist and typed didrowat, and xcode suggested this didEndEditingRowAt :)
override func tableView(_ tableView: UITableView, didEndEditingRowAt indexPath: IndexPath?) {
tableView.selectRow(at: IndexPath(row: 0, section: 0), animated: true, scrollPosition: .middle)
}
Now first part of question is answered, I've inserted selection there.
The second question is still opened, how to make selected row keeping still selected while I am removing another row. I don't need selected row to deselect at all if I am removing another one.

Related

tableView is not removing the last deleted cell immediately

I'm having trouble removing the last cell I have tried tableView.reloadData() and beginUpdate(), endUpadate(), and all these methods works fine if I have more than one cell, but when I come to deleting the last cell it didn't work and the tableView won't reloadData at the same time that I delete the last cell, other cells 2-3-4 no problem, Plus when I close the app everyThing works fine.
im deleting the cells from the firebase store its a document that contains data if concern
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
if editingStyle == .delete {
print("Deleted")
self.DriverOffers.remove(at: indexPath.row)
self.DriverOrdersTV.deleteRows(at: [indexPath], with: .automatic)
self.DriverOrdersTV.reloadData()
}else if editingStyle == .insert {
self.DriverOrdersTV.beginUpdates()
self.DriverOrdersTV.insertRows(at: [IndexPath.init(row: 0, section: 0)], with: .automatic)
self.DriverOrdersTV.endUpdates()
}
}

Deleting row (or array item) permanently - swift 3/4

After successfully deleting a row from UITableView, I go to another view controller but when I return to the UITableView the deleted row is back again. Am I missing something? I am relatively new to Swift.
Here is the code:
func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]? {
let delete = UITableViewRowAction(style: .destructive, title: "Delete") { (action, indexPath) in
self.queuelayout.remove(at: indexPath.row)
tableView.deleteRows(at: [indexPath], with: .fade)
print(self.queuelayout)
}
return [delete]
}
I've also tried with this code:
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
if editingStyle == .delete{
queuelayout.remove(at: indexPath.row)
tableView.deleteRows(at: [indexPath], with: .right)
}
}
Look forward to your help.
I checked your top codes. They are all right. The only possible reason is as you said you went to another VC , you have already get rid of your tableViewController from the memory. Here is an simple example:
If your tableView is the most right one, and when you go back to middle vc, your right one will be removed from the memory. Then when you click assign button and actually, you are loading a completely new tableViewController.
As a result, viewDidLoad will be called and your tableViewController will init again to the original states.
You may set a breakpoint at func viewDidLoad(), to check this situation. If this one is not called when you go back, you are good to go. Otherwise, everything will be reset. All what you delete will reappear as they should.
This is a simple example. Your case may be a little complicated. But if your tableviewcontroller called ViewDidLoad(), you must have some hassles somewhere.
Hope this help you out.

Ending editing after everything in UITableView section was deleted

My project contains a tableview. This tableview consists of 2 sections. The first section contains a single cell that is not editable. The second section is populated by an array called data.
There is a button that starts editing mode and allows the user to delete content from the second section.
I'm trying to end editing mode when the second section is empty so that i can select the cell in my first section.(aesthetic purposes)
My code looks like this (simplified, not actual code):
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
data.remove(at: indexPath.row)
tableView.deleteRows(at: [indexPath], with: .fade)
if(data.count==0) {
self.tableView.setEditing(false, animated: true)
self.tableView.selectRow(at: IndexPath(row: 0, section: 0), animated: false, scrollPosition: .top)
}
This leads to all kinds of weird bugs. Which, according to the documentation, is expected:
You should not call setEditing:animated: within an implementation of this method. If for some reason you must, invoke it after a delay by using the performSelector:withObject:afterDelay: method.
It works, but I feel like this would be a hacky solution. It is not clear to me why I should not end editing when everything is deleted. Can someone explain this? Or perhaps any alternatives?

Insert new row at the bottom upon deleting a row in UITableview

I have a requirement where I need to show a tableview with three rows always.
When user swipes to delete a row, I need to add a new row at the bottom.
While this happens, the swipe animation which moves the row to the left to delete has to be retained. I mean delete animation should not be affected. Is this possible?
First, your dataSource must return always 3 for your numberOfRows(in:) method. Then you can commit changes this way:
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
if editingStyle == .delete {
tableView.performBatchUpdates({
// Delete the swiped row
tableView.deleteRows(at: [indexPath], with: .left)
// Get the last row index (numberOfRows-1)
let lastRowIndex = tableView.numberOfRows(inSection: indexPath.section)-1
// Insert a new row at the end
tableView.insertRows(at: [IndexPath(row: lastRowIndex, section: 0)], with: .top)
}, completion: nil)
}
}
Don't forget to update the rest of your dataSource accordingly, because cells may be reused. The code need to be added before call performBatchUpdates. Something like that:
var cellsText = ["A","B","C"]
// Inside your tableView(:commit:forRowAt) method:
if editingStyle == .delete {
cellsText.remove(at: indexPath.row)
cellsText.append("D")
// ...
}

How to disable swipe to delete option at 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!

Resources