0

I have implemented the delete functionality for any row based on the index passed.

Each cell has a button to initiate delete for that row. I take the cell.tag to detect the row and pass to delete function which uses indexPath and deleteRowAtIndexPaths(...).

Now, the problem happens when I keep on deleting the 0th row. Initially, it deletes correctly. 0th row is gone. 1st row replaces the 0th row. Now, if I delete 0th row again, it deletes the current 1st row.

The reason I understood is that cell.tag is not updated. What exactly an I doing wrong ? The problem is not consistent. If I wait between the deletes, it is ok. If I delete one row after another. It keeps on deleting some other row.

How should I proceed now ? I have searched for this already and unable to find proper solution or guide ?

Here are the main pieces of code

// Typical code having Programmatic UITableView
// ...

func addTestEvent(cell: MyCell) {
    func onSomeAction() {
        dispatch_async(dispatch_get_main_queue(), {
            self.removeRow(cell.tag)
        })
    }

    ...
    // onSomeAction() called on click on the button
}


func test(cell: MyCell) -> () {
    ...
    addTestEvent(cell)

}

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCellWithIdentifier( NSStringFromClass(MyCell), forIndexPath: indexPath) as! MyCell
    cell.tag = indexPath.row
    cell.test = { (cell) in self.test(cell) }
    return cell
}


func removeRow(row: Int) {
    let indexPath = NSIndexPath(forItem: row, inSection: 0)
    tableView.beginUpdates()
    posts.removeAtIndex(row)
    tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Automatic)
    tableView.endUpdates()
}
mythicalcoder
  • 3,143
  • 1
  • 32
  • 42
  • 2
    How can we assume that your cell.tag is updated or not updated? Post your code atleast which you assume is causing the issue. – Santosh Sep 21 '16 at 16:45
  • @Santosh Please check now. This are only main pieces of code. But you will understand. Let me know if not sufficient, I will add further code. – mythicalcoder Sep 21 '16 at 17:00
  • `deleteRowsAtIndexPaths` does not call `cellForRowAtIndexPath` so the cell is not updated. Anyway it's not good practice to keep the indexPath as tag in the cell. Maintain the data source, not the view. – vadian Sep 21 '16 at 17:03
  • New to iOS. Thanks. Can you tell me how I should be deleting the row given I require this kind of an architecture. I did the entire thing programmatically. – mythicalcoder Sep 21 '16 at 17:06
  • @vadian would you look at this question ? http://stackoverflow.com/questions/39195116/create-uitableview-programmatically-in-ios-swift-table-height-not-auto-resizing – mythicalcoder Sep 22 '16 at 09:36

2 Answers2

0

The key point is not to use cell.tag to identify the cell. Rather use the cell directly. Thanks Vadian for the comment. It is not a good practice to keep indexPath in cell tag. Now I know why !

This answer gave me the major hint to resolve the problem. https://stackoverflow.com/a/29920564/2369867

// Modified pieces of code. Rest of the code remain the same.

func addTestEvent(cell: MyCell) {
    func onSomeAction() {
        dispatch_async(dispatch_get_main_queue(), {
            self.removeRow(cell)
        })
    }
    // ...
    // onSomeAction() called on click on the button
}

func removeRow(cell: UITableViewCell) {
    let indexPath = tableView.indexPathForRowAtPoint(cell.center)!
    let rowIndex = indexPath.row
    // ...
}
Community
  • 1
  • 1
mythicalcoder
  • 3,143
  • 1
  • 32
  • 42
0

Add tableView.reloadData() after deleting a cell. That worked for me.

Stephen Kennedy
  • 20,585
  • 22
  • 95
  • 108