I have a UICollectionView
where I use the function didSelectItemAtIndexPath
to select a cell and change its alpha.
In the UICollectionView
there are 12 cells.
In Order to take the deselected cells back to alpha = 1.0
I use the function didDeselectItemAtIndexPath
.
So far the code works however, when I select a cell and I scroll the UICollectionView
the app crashes on the line let colorCell : UICollectionViewCell = collectionView.cellForItemAtIndexPath(indexPath)!
inside the deselect function with the error:
fatal error: unexpectedly found nil while unwrapping an Optional value
(lldb)
I think I need to reload the collection view but How can I reload and keep the cell selected?
override func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) {
let colorCell : UICollectionViewCell = collectionView.cellForItemAtIndexPath(indexPath)!
colorCell.alpha = 0.4
}
override func collectionView(collectionView: UICollectionView, didDeselectItemAtIndexPath indexPath: NSIndexPath) {
let colorCell : UICollectionViewCell = collectionView.cellForItemAtIndexPath(indexPath)!
colorCell.alpha = 1.0
}
Crash happened because the cell that you selected and scrolled out of the visible region of the screen had been reused for other cells in the collection view. Now, when you try to fetch that selected cell in didDeselectItemAtIndexPath
using cellForItemAtIndexPath
, it resulted in a crash.
To avoid crash, as mentioned by @Michael Dautermann, use optional binding to validate if the cell is nil and then set the alpha
func collectionView(collectionView: UICollectionView, didDeselectItemAtIndexPath indexPath: NSIndexPath) {
if let cell = collectionView.cellForItemAtIndexPath(indexPath) {
cell.alpha = 1.0
}
}
In order to persist your selection state during scrolling, check the cell's selection state and set your alpha
value accordingly when you dequeue your cell in cellForItemAtIndexPath
method
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCellWithReuseIdentifier("Cell", forIndexPath: indexPath)
if cell.selected {
cell.alpha = 0.4
}
else {
cell.alpha = 1.0
}
return cell
}
cellForItemAtIndexPath
seems to be returning an optional, so why not do:
override func collectionView(collectionView: UICollectionView, didDeselectItemAtIndexPath indexPath: NSIndexPath) {
if let colorCell = collectionView.cellForItemAtIndexPath(indexPath) {
colorCell.alpha = 1.0
}
}