6

I have a calculator class, a first ViewController to insert the values and a second ViewController to show the result of the calculation. Unfortunately I get a error called "Can't unwrap Optional.None" if I click the button. I know it's something wrong with the syntax, but I don't know how to improve it.

The button in the first Viewcontroller is set to "Segue: Show (e.g. Push)" in the storyboard to switch to the secondViewController if he gets tapped.

the calculator class is something like:

class Calculator: NSObject {

    func calculate (a:Int,b:Int) -> (Int) {
        var result = a * b
        return (result)
    }
}

The Viewcontroller calls the function, inserts a/b and wants to change the label which is located in the secondviewcontroller:

class ViewController: UIViewController {

@IBAction func myButtonPressed(sender : AnyObject) {
    showResult()
}

var numberOne = 4
var numberTwo = 7

var myCalc = Calculator()

func showResult () {
    var myResult = myCalc.calculate(numberOne, b: numberTwo)
    println("myResult is \(String(myResult))")
    var myVC = secondViewController()
    myVC.setResultLabel(myResult)
}

And here is the code of the secondViewController

class secondViewController: UIViewController {

@IBOutlet var myResultLabel : UILabel = nil

func setResultLabel (resultValue:Int) {
    myResultLabel.text = String(resultValue)
}

init(coder aDecoder: NSCoder!)
{
    super.init(coder: aDecoder)
}
5
  • What is your question? Commented Jun 4, 2014 at 17:47
  • How are you changing between the UIViewControllers? Commented Jun 4, 2014 at 17:47
  • Thank you guys, I added the information in my first post. I just realized that I had to create an instance of my class, which is now called "myVC". Unfortunately I get another error called "Can't unwrap Optional.None" now. Commented Jun 4, 2014 at 17:51
  • In showResult() where is the value of secondViewController coming from? Is is a global variable? It doesn't look like an attribute in your ViewController class. Can you use println() (or the debugger) to see it's value before calling setResultLabel()? Commented Jun 4, 2014 at 17:56
  • create a custom init and pass it in there... ? Commented Jun 4, 2014 at 18:02

3 Answers 3

17

In Swift, everything is public by default. Define your variables outside the classes:

import UIKit

var placesArray: NSMutableArray!

class FirstViewController: UIViewController {
//
..
//
}

and then access it

import UIKit

class TableViewController: UITableViewController {
//
placesArray = [1, 2, 3]
//
}
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks a lot. I was going crazy to pass the string from NSViewController to NSView of Popover and your solution saved me.
3

The problem here is that the FirstViewController has no reference to the instance of SecondViewController. Because of this, this line:

secondViewController.setResultLabel(myResult)

does nothing (except probably causing the Can't unwrap Optional.None error). There are a few ways to solve this problem. If you are using storyboard segues you can use the -prepareForSegue method of UIViewController. Here is an example:

In FirstViewController:

override func prepareForSegue(segue: UIStoryboardSegue!,sender: AnyObject!){         
  //make sure that the segue is going to secondViewController
  if segue.destinationViewController is secondViewController{
    // now set a var that points to that new viewcontroller so you can call the method correctly
    let nextController = (segue.destinationViewController as! secondViewController)
    nextController.setResultLabel((String(myResult)))
  }
}

Note: this code will not run as is because the function has no access to the result variable. you'll have to figure that out yourself :)

Comments

0

I think the issue here is, you are trying to set the UI component (here, its the label : myResultLabel)

When segue is fired from first view controller, the second view has not yet been initialized. In other words, the UI object "myResultLabel" is still nil.

To solve this, you will need to create a local string variable in second controller. Now, set that string to what you are trying to display, and finally, set the actual label in "viewDidLoad()" of the second controller.

Best Regards, Gopal Nair.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.