Please help me find what is my mistake. I have a table view the data source is an array called items. After one item has been deleted from the items array the cellForRowAt method called and the parameter indexPath.row is equals with items.count. This happens only, when the rows count is just enough to one item is out of the table view's view. When it happens it cause a fatal error (index out of range). A hack is used in this case and the value of the IndexPath.row be decreased.
Please see the following image:
The following code for cellForRowAt:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
{
let cell = tableView.dequeueReusableCell(withIdentifier: "ItemCell", for: indexPath) as! ItemCell
var i = indexPath.row
if i >= items.count { i = items.count - 1 } //XXX: hack! Sometimes called with indexPath.row is equal with items.count :(
cell.set(items[i])
return cell
}
And the following code for the delete:
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath)
{
if (editingStyle == UITableViewCellEditingStyle.delete)
{
items.remove(at: indexPath.row)
tableView.deleteRows(at: [indexPath], with: UITableViewRowAnimation.fade)
}
}
I think is not relevant, but I'm using iOS 11.0
UPDATE
I tried, and the following very simple code is also affected:
class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate
{
var items = ["0","1","2","3","4","5","6","7","8","9","A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z"]
override func viewDidLoad()
{
super.viewDidLoad()
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
return items.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
{
let cell = tableView.dequeueReusableCell(withIdentifier: "ItemCell", for: indexPath)
cell.textLabel?.text = "\(items[indexPath.row])"
return cell
}
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath)
{
if (editingStyle == UITableViewCellEditingStyle.delete)
{
items.remove(at: indexPath.row)
tableView.deleteRows(at: [indexPath], with: UITableViewRowAnimation.fade)
}
}
}
How to reproduce:
- Scroll to down to Y be the last item on your screen
- Try to delete Y swiping to the left
- And getting the following error