简体   繁体   中英

UICollectionView crashing after scroll and selecting cell

I have a Horizontal CollectionView which has cells with one image view inside. What i want to do is set a default selected cell. Selected cell should change its image color. And after if user select some other cell it should be selected and default selected cell should be deselected. Currently all of those are working. But sometimes when i'm scroll and selecting a cell its crashing saying as follow.

ERROR: unexpectedly found nil while unwrapping an Optional value

Here is my complete code

    override func viewDidLoad() {
            super.viewDidLoad()
            self.collectionView.delegate = self
            self.locationManager.delegate = self
            collectionView.allowsMultipleSelection = false
        }

    func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
            return CatNames.count
        }


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

                let cell = collectionView.cellForItemAtIndexPath(indexPath) as! CategoryCell
                cell.CarImage.image = UIImage(named: CatImages[indexPath.row])?.maskWithColor(UIColorFromRGB(0xEA7C6A))
                cell.Name.textColor = UIColorFromRGB(0xEA7C6A)

        }

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

                let cell = collectionView.cellForItemAtIndexPath(indexPath) as! CategoryCell
                cell.CarImage.image = UIImage(named: CatImages[indexPath.row])
                cell.Name.textColor = UIColor.darkGrayColor()

        }

        func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
            let cell = collectionView.dequeueReusableCellWithReuseIdentifier("cell", forIndexPath: indexPath) as! CategoryCell

            cell.Name.text = CatNames[indexPath.row]


            // setup selectedBackgroundView
            if(cell.selected == true){
                cell.CarImage.image = UIImage(named: CatImages[indexPath.row])!.maskWithColor(UIColorFromRGB(0xEA7C6A))
                cell.Name.textColor = UIColorFromRGB(0xEA7C6A)
            }
            else{
                cell.CarImage.image = UIImage(named: CatImages[indexPath.row])
                cell.Name.textColor = UIColor.darkGrayColor()
            }


            return cell
        }


        override func viewWillAppear(animated: Bool) {
            super.viewWillAppear(animated)
            let indexPath = NSIndexPath(forRow: 0, inSection: 0)
            self.collectionView.selectItemAtIndexPath(indexPath, animated: false, scrollPosition: .None)
        }

extension UIImage {
    func maskWithColor(color: UIColor) -> UIImage? {

        let maskImage = self.CGImage
        let width = self.size.width
        let height = self.size.height
        let bounds = CGRectMake(0, 0, width, height)

        let colorSpace = CGColorSpaceCreateDeviceRGB()
        let bitmapInfo = CGBitmapInfo(rawValue: CGImageAlphaInfo.PremultipliedLast.rawValue)
        let bitmapContext = CGBitmapContextCreate(nil, Int(width), Int(height), 8, 0, colorSpace, bitmapInfo.rawValue) //needs rawValue of bitmapInfo

        CGContextClipToMask(bitmapContext, bounds, maskImage)
        CGContextSetFillColorWithColor(bitmapContext, color.CGColor)
        CGContextFillRect(bitmapContext, bounds)

        //is it nil?
        if let cImage = CGBitmapContextCreateImage(bitmapContext) {
            let coloredImage = UIImage(CGImage: cImage)

            return coloredImage

        } else {
            return nil
        }
    }
}
     func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) {
            guard collectionView.cellForItemAtIndexPath(indexPath) != nil else {
                  return
            }
            let cell = collectionView.cellForItemAtIndexPath(indexPath) as! CategoryCell
            cell.CarImage.image = UIImage(named: CatImages[indexPath.row])?.maskWithColor(UIColorFromRGB(0xEA7C6A))
            cell.Name.textColor = UIColorFromRGB(0xEA7C6A)

    }

    func collectionView(collectionView: UICollectionView, didDeselectItemAtIndexPath indexPath: NSIndexPath) {
            guard collectionView.cellForItemAtIndexPath(indexPath) != nil else {
                  return
            }
            let cell = collectionView.cellForItemAtIndexPath(indexPath) as! CategoryCell
            cell.CarImage.image = UIImage(named: CatImages[indexPath.row])
            cell.Name.textColor = UIColor.darkGrayColor()

    }

This basically answers your question because on this part of your code

   let cell = collectionView.cellForItemAtIndexPath(indexPath) as! CategoryCell

You're basically hard casting it using as! and the app will crash if the value of collectionView.cellForItemAtIndexPath(indexPath) is nil

Alternatively you can also use the if let syntax instead of guard else

if let cell = collectionView.cellForItemAtIndexPath(indexPath) {
    let aCell = cell as! CategoryCell
    // do stuff here
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM