Haox
Haox

Reputation: 708

Add button only in Code?

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?

Upvotes: 0

Views: 233

Answers (3)

Caleb
Caleb

Reputation: 124997

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.

Upvotes: 2

Vinzzz
Vinzzz

Reputation: 11724

"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... :-)

Upvotes: 1

Valentin
Valentin

Reputation: 3302

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.

Upvotes: 1

Related Questions