0

I'm trying to add a button only in code. In the Xcode Simulator it works perfectly but not on my device :

fatal error: unexpectedly found nil while unwrapping an Optional value

My code:

@IBOutlet weak var playButton: UIButton!

override func viewDidLoad() {

    super.viewDidLoad()

    let image = UIImage(named: "playButton.png") as UIImage

    playButton   = UIButton.buttonWithType(UIButtonType.System) as UIButton
    playButton.frame = CGRectMake(10, 10, 100, 100) // crash is here
    playButton.center = CGPointMake(self.frame.width/2, self.frame.height/1.7)

    playButton.addTarget(self, action: "transition:", forControlEvents: UIControlEvents.TouchUpInside)
    playButton .setBackgroundImage(image, forState: UIControlState.Normal)

    self.view?.addSubview(playButton)

}

Someone can help me?

7
  • What do you mean it doesn't work on your device? Saying it doesn't work is useless. Commented Oct 8, 2014 at 17:55
  • I can't launch it, I have a fatal error : "fatal error: unexpectedly found nil while unwrapping an Optional value" Commented Oct 8, 2014 at 17:57
  • Where is the code you provide? is this code inside your viewController's viewDidLoad method? Commented Oct 8, 2014 at 18:09
  • Yes it is. You can see my edit Commented Oct 8, 2014 at 18:09
  • shouldn't IBOutlet be written outside of it ? Also self.frame is indeed self.view.bounds, no? Commented Oct 8, 2014 at 18:11

3 Answers 3

2

In the Xcode Simulator it works perfectly but not on my device

That often means that you have a mismatch between your code and the actual name of a file. The MacOS X filesystem is normally not case sensitive, while the iOS file system is case sensitive. So, if your image file is named something like PlayButton.png or playButton.PNG but you specify playButton.png, it'll generally work on the simulator but not on the device.

Make sure that the filenames in your code match the files in your project.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks! I know about case sensitivity but it's not the problem. I checked and it's ok
1

That makes no sense - if you are using @IBOutlet that means that your button is created in the storyboard, therefore you do NOT need to initialize it:

let image = UIImage(named: "playButton.png") as UIImage

playButton   = UIButton.buttonWithType(UIButtonType.System) as UIButton
playButton.frame = CGRectMake(10, 10, 100, 100) // crash is here
playButton.center = CGPointMake(self.frame.width/2, self.frame.height/1.7)

playButton.addTarget(self, action: "transition:", forControlEvents: UIControlEvents.TouchUpInside)
playButton .setBackgroundImage(image, forState: UIControlState.Normal)

self.view?.addSubview(playButton)

Remove all of the above code and set that up in the storyboard instead. @IBAction should be a separate method which is hooked up to your touchUpInside of your button in your storyboard.

3 Comments

Thank you! I removed @IBOutlet because I want my button only in code and it works like that.
Do you know how can I add the button on a scene ? When I add my code (without @IBOutlet) on my GameScene the button doesn't appear. Do you know why ?
Haox, if you are referring to SpriteKit scene I would check stackoverflow.com/questions/19082202/… answer
1

"Unwrapping an optionnal value" seem to refer to the ! next to your var declaration... What if you use ? instead ?

From Swift doc

Trying to use ! to access a non-existent optional value triggers a runtime error. 
Always make sure that an optional contains a non-nil value before using ! to force-unwrap its value.

Try this:

weak var playButton : UIButton?

and add ? after it when accessing it - like you do with self.view?.addSubview or locally force unwrapp it with ! in methods where you know it has already been created

(I'm not sure though, still learning the language... :-)

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.