krystiangonczi
krystiangonczi

Reputation: 11

Crash while adding UIImage from code

I'm a Swift beginner and I'm writing an app that will show a list of things. When you click on one of them, you'll get detailed information about it and a photo. However, I've got one problem - I've got code to show the image, but when I click in simulator it crashes.

Text that is on the bottom of xcode when the app crashes:

fatal error: unexpectedly found nil while unwrapping an Optional value

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
    var detail = segue.destinationViewController as! detailSkinsViewController
    detail.skinNameLabel = self.skin
    if (self.skin == "AK47 | Wasteland Rebel") {
        detail.skinImg.image = UIImage(named: "s495fn")
    }
}

Thanks!

Upvotes: 0

Views: 1434

Answers (3)

Rob Napier
Rob Napier

Reputation: 299643

You should look at the crash stack to see the actual line. There are a couple of places you could have trouble:

var detail = segue.destinationViewController as! detailSkinsViewController

This requests a crash if destinationViewController is not of class detailSkinsViewController. (Swift classes should always begin with a capital letter. This should also be a let, not var. You never modify it.) Using if-let here would be much safer.

    detail.skinImg.image = UIImage(named: "s495fn")

It's very unclear what these are, but if skinImg is a UIImageView!, then you would expect this to crash if it the destination NIB has not been loaded yet (which is likely). You generally should never reach into other objects IBOutlets for exactly this reason. (This is also a good reason to use ? rather than ! for IBOutlets. That would lead to just "nothing happens" rather than a crash.)

Rather than messing with another view controllers outlets, you should create a UIImage? property on the view controller itself. In its didSet, update the UIImageView if the view is loaded (isViewLoaded). During viewDidLoad, initialize the UIImageView using the property. This way, you have a clear API for others to set the image that doesn't expose your internal subviews (which are implementation details).

As an example:

class ViewController: UIViewController {
    @IBOutlet private var imageView: UIImageView?
    var image: UIImage? {
        didSet(newImage) {
            self.imageView?.image = newImage
        }
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        self.imageView?.image = self.image
    }
}

Upvotes: 3

praths
praths

Reputation: 353

This Error comes normally when trying to unwrap a value of an optional variable which has no value at all. First check your optional variables and debug line by line to see if any of the Optional variables has no value at all which you had been trying to unwrap

Upvotes: 0

Özgür Ersil
Özgür Ersil

Reputation: 7013

You should check your optional values, i did not see your skin variable definition but i think that code below will solve your problem

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
    if let detail = segue.destinationViewController as!  detailSkinsViewController {
           detail.skinNameLabel = self.skin
           if (self.skin == "AK47 | Wasteland Rebel") {
              detail.skinImg.image = UIImage(named: "s495fn")
           }
      }
}

Upvotes: 0

Related Questions