Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

delete row UITableView index issue

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.

like image 227
BlueBoy Avatar asked Apr 29 '17 07:04

BlueBoy


People also ask

How to remove cell UITableView?

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.

What does indexPath row return?

indexPath(for:) Returns an index path that represents the row and section of a specified table-view cell.

What is indexPath row?

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.


3 Answers

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 .

like image 157
Dhiru Avatar answered Oct 17 '22 11:10

Dhiru


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.

like image 2
Pitiphong Phongpattranont Avatar answered Oct 17 '22 11:10

Pitiphong Phongpattranont


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)
      }
    
like image 2
vadian Avatar answered Oct 17 '22 13:10

vadian