2

I have a problem when I quickly selecting and deselecting rows in my collectionView. I have a map and above it i have a horizontal collectionView that i choose what i want to see.

func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) {

        let selectedCell:UICollectionViewCell = collectionView.cellForItemAtIndexPath(indexPath)!
        selectedCell.contentView.backgroundColor = UIColor(red: 102/256, green: 255/256, blue: 255/256, alpha: 0.66)
        switch indexPath.row {
        case 0:
            query0()
            break
        case 1:
            query1()
            break
        case 2:
            query2()
            break
        case 3:
            query3()
            break
        default:

            break
        }

    }

and the code for deselecting is:

 func collectionView(collectionView: UICollectionView, didDeselectItemAtIndexPath indexPath: NSIndexPath) {
        let cellToDeselect:UICollectionViewCell = collectionView.cellForItemAtIndexPath(indexPath)!
        cellToDeselect.contentView.backgroundColor = UIColor.clearColor()
    }

The error i get is this:

fatal error: unexpectedly found nil while unwrapping an Optional value

When i tried to selecting slowly the cells i didn't get the error But if i do it quickly it crashes

I commented the deselect function and i didn't get any errors (and i check it with quick change of cells)

Nirav D
  • 71,513
  • 12
  • 161
  • 183
mike vorisis
  • 2,786
  • 6
  • 40
  • 74
  • take a look at this unswear http://stackoverflow.com/a/22861956/4525866 – salabaha Jul 01 '16 at 10:17
  • thanks for your answer. i took a look in that but i think it's a bit different with mine. his always nil but mine if i do it slowly there isn't a problem... – mike vorisis Jul 01 '16 at 10:23

4 Answers4

4

Instead of changing color in didSelect and didDeSelect try something like this

 func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell
{
     let cell = collectionView.dequeueReusableCellWithReuseIdentifier("CustomCell", forIndexPath: indexPath) as! CustomCell
     let view = UIView(frame: cell.contentView.bounds)
     view.backgroundColor = UIColor(red: 102/256, green: 255/256, blue: 255/256, alpha: 0.66)
     cell.selectedBackgroundView = view
}

Hope this will help you.

Nirav D
  • 71,513
  • 12
  • 161
  • 183
2

Your app is crashing Because you are getting nil when you access invisible cell using

 let cellToDeselect:UICollectionViewCell = collectionView.cellForItemAtIndexPath(indexPath)!

Make cellToDeselect varible as optional & use optional chaining while changing color.

Replace your code with this

let cellToDeselect:UICollectionViewCell? = collectionView.cellForItemAtIndexPath(indexPath)?
        cellToDeselect?.contentView.backgroundColor = UIColor.clearColor()
Rohit Pradhan
  • 3,867
  • 1
  • 21
  • 29
2

Don't force unwrapping the result of cellForItemAtIndexPath. You can use an if let statement:

func collectionView(collectionView: UICollectionView, didDeselectItemAtIndexPath indexPath: NSIndexPath) {
        if let cellToDeselect = collectionView.cellForItemAtIndexPath(indexPath) {
        cellToDeselect.contentView.backgroundColor = UIColor.clearColor()
       }
    }
t4nhpt
  • 5,264
  • 4
  • 34
  • 43
2

As someone else already said, you are getting nil because you force unwrap a cell which is not available for some reason. Force unwrapping is quite dangerous and you should try to avoid it. There are various ways to do this, you could either do what Rohit KP stated and use optional for the assigning variable, or you could do it like this (which I prefer):

if let cellToDeselect = collectionView.cellForItemAtIndexPath(indexPath) as? UICollectionViewCell {
   cellToDeselect.contentView.backgroundColor = UIColor.clearColor()
}

This is assigning the variable the way you want, and if it's not returning a nil value it will go into the if statement block and execute your code. The reason I like this way better is because it is easier to read. You know for a fact that you cannot enter this closure if your object is nil, and you also don't have to force unwrap or assign any optional variables, so you have a clear overview of when this code is running and you also know that it's safe.

ClockWise
  • 1,509
  • 15
  • 32