I'm using the code below to delete a row in my tableview. First I delete the object from my array and then from the tableview using this code:
let i = IndexPath(item: rowNum, section: 0)
myArray.remove(at: rowNum)
myTableView.deleteRows(at: [i], with: UITableViewRowAnimation.left)
However, if I delete another row right after, not the row I wanted to be deleted gets deleted. The issue is, even though I deleted the first item in the tableview (e.g. index 0), clicking on the new first row returns index 1... which is wrong, and deletes the second row. After deleting the first row the new row at the top should have an index of 0.
I can solve this problem by doing:
mTableView.reloadData()
but this seems wrong... I shouldn't have to reload all the data again.
What else can I do?
EDIT: I have a custom button in my tableviewcell I am pressing to delete the row - not swiping.
So, to remove a cell from a table view you first remove it from your data source, then you call deleteRows(at:) on your table view, providing it with an array of index paths that should be zapped. You can create index paths yourself, you just need a section and row number.
indexPath(for:) Returns an index path that represents the row and section of a specified table-view cell.
Index paths describe an item's position inside a table view or collection view, storing both its section and its position inside that section. For example, the first row in a table would have section 0, row 0, whereas the eighth row in the fourth section would have section 3, row 7.
Problem
The problem in you case is the Tag you are setting on the Button , button Tag is not changed when you are deleting the Rows , as its the All Cell is not Reloaded.
i guess you are setting tag in cellforRowIndexpath
you try with putting tag on button in tableWillDisplayCell
or
the best way to do this is below .
Solution
you can get the IndexPath
in other way
Suppose if your view hierarchy is
UITableViewCell-> contentView -> button
in you button click method
if let cell = sender.superview?.superview as? UITableviewCell{
let indexPath = myTableView.indexPath(for: cell)
// Now delete the table cell
myArray.remove(at: indexPath.row)
myTableView.beginUpdates()
myTableView.deleteRows(at: [indexPath], with: UITableViewRowAnimation.left)
myTableView.endUpdates()
}
i hope this will work for you .
I think you store rowNum
variable with your cell and it's set in cellForRow(at:)
method. If what I think is right then here's a thing.
UITableView
try to do at least work as possible. This means that after you delete a cell, UITableView
won't gonna call cellForRow(at:)
methods on its datasource again until you call reloadData()
or reloadRows(at:animation:)
methods.
So when you delete the first cell, rowNum
variable on other cells won't gonna be updated until you call reloadData()
as you tried and saw that's work.
My suggestion is don't keep rowNum
variable at a cell but ask UITableView
for the index path of any cell via indexPath(for:)
method on UITableView
instead.
Smart solution to delete a row when a button is pressed in the corresponding cell.
In the custom cell class declare a callback variable
var callback : ((UITableViewCell)->())?
In the custom cell class implement an IBAction
and connect the button to that action
@IBAction func buttonPressed(_ sender : UIButton) {
callback?(self)
}
In cellForRowAtIndexPath
assign the closure containing the code to delete the cell
cell.callback = { currentCell in
let actualIndexPath = tableView.indexPath(for: currentCell)!
self.myArray.remove(at: actualIndexPath.row)
tableView.deleteRows(at: [actualIndexPath], with: .left)
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With