OlegA
OlegA

Reputation: 11

Index out of range when delete cell

Hi and hope you'll help.

In every cell I have a text field which responds directly from table view. I save data via closure in cell.

cell.tableViewClosure = {[unowned self] in
    self.tableView.beginUpdates()
    // Singleton
    Strings.shared.strings[indexPath.row] = cell.textField.text!
    self.tableView.reloadRows(at: [indexPath], with: .automatic)
    self.tableView.endUpdates()
}

By instance i delete first cell, data array count and number of rows are equal after in log, but if I try to edit text field in last cell and tap return, app crashes with index out of range.

If log during deletion - it is 5 strings in array, but indexPath.row for this proper cell is 5.

But if I reload data in deletion - everything fine with edit last cell but UI is not smooth.

Upvotes: 1

Views: 1044

Answers (3)

Shockki
Shockki

Reputation: 61

Use tableView.indexPath(for: cell) to get the current index

Upvotes: 0

Paulw11
Paulw11

Reputation: 114875

Your problem is that indexPath.row is captured when you assign the closure, for your last cell, it will have the value "4". If you subsequently delete an earlier cell, the last element in your array is now "3", but the captured value doesn't change; it is still 4.

When you then edit the text field in the last cell, the captured value 4 is used to access your model and you get an array bounds exception.

You can use indexPath(for:) to determine the appropriate index path when the closure executes:

cell.tableViewClosure = {[unowned self] in
    if let indexPath = self.tableView.indexPath(for: cell) {
        self.tableView.beginUpdates()
        Strings.shared.strings[indexPath.row] = cell.textField.text!
        self.tableView.reloadRows(at: [indexPath], with: .automatic)
        self.tableView.endUpdates()
    }
}

Upvotes: 2

R Bradshaw
R Bradshaw

Reputation: 183

indexPath.row starts with 0. So the range will be 0-4. If you're using 5 strings in an array and using a .count - that will return a 5.

Just do indexPath.row - 1 to adjust for the off by 1 (index out of range).

Upvotes: 1

Related Questions