mike vorisis
mike vorisis

Reputation: 2832

Error while selecting and deselecting rows in collectionview

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)

Upvotes: 2

Views: 448

Answers (4)

ClockWise
ClockWise

Reputation: 1519

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.

Upvotes: 2

Nirav D
Nirav D

Reputation: 72460

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.

Upvotes: 4

t4nhpt
t4nhpt

Reputation: 5302

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()
       }
    }

Upvotes: 2

Rohit Pradhan
Rohit Pradhan

Reputation: 3875

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()

Upvotes: 2

Related Questions