Reputation: 2832
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
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
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
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
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