How to avoid mistakes index out of range?

2019-07-16 02:14发布

问题:

I try to select multiple items in collectionCell, but if i tap many times for deselect cell i get an error Thread 1: Fatal error: Index out of range

On this line selectedTimeIntervalArray.remove(at: indexPath.item) on indexPath.item == 1.

How to avoid this error?

func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {

    let selectedCell = collectionView.cellForItem(at: indexPath)

    if indexPath.item == 0 {
        selectedBackgroundColor(cell: selectedCell!)
        selectedTime = timeIntervalArray[indexPath.item]
        selectedTimeLabel.text = "Время - \(selectedTime)"
        selectedTimeIntervalArray.append(selectedTime)
    } else if indexPath.item == 1 {
        selectedBackgroundColor(cell: selectedCell!)
        selectedTime2 = timeIntervalArray[indexPath.item]
        selectedTimeIntervalArray.append(selectedTime2)
    }

}

func collectionView(_ collectionView: UICollectionView, didDeselectItemAt indexPath: IndexPath) {

    let deselectedCell = collectionView.cellForItem(at: indexPath)

    if indexPath.item == 0 {
        deselectedBackgroundColor(cell: deselectedCell!)
        selectedTime = ""
        selectedTimeIntervalArray.remove(at: indexPath.item)
    } else if indexPath.item == 1 {
        deselectedBackgroundColor(cell: deselectedCell!)
        selectedTime2 = ""
        selectedTimeIntervalArray.remove(at: indexPath.item)
    }

}

回答1:

Let's say you select the cell at indexPath.item == 1. You do then

selectedTime2 = timeIntervalArray[indexPath.item]
selectedTimeIntervalArray.append(selectedTime2)

So we have: selectedTimeIntervalArray == ["ValueOfSelectedTime2"]

Now, we deselect the item. You do then:

selectedTimeIntervalArray.remove(at: indexPath.item)

So you do in our case:

selectedTimeIntervalArray.remove(at: 1)

Index 1, really? No, that causes a crash. Because selectedTimeIntervalArray has only one item and it's at index 0.

indexPath.item is not the index of the object you stored in your array.

Instead, retrieve first the correct index:

let objectToRemove = timeIntervalArray[indexPath.item]‌
let index = selectedTimeIntervalArray.index(of: objectToRemove​)

Then remove it:

 selectedTimeIntervalArray.remove(at: index)