4

I am trying to pass an int variable between views in Swift but I'm not sure how to access the other View controller's property.

In Objective C I would do something like this

UIStoryboard *storyBoard = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
AnsViewController *ansViewController = [storyBoard instantiateViewControllerWithIdentifier:@"ansView"];
ansViewController.num = theNum;
[self presentViewController:ansViewController animated:YES completion:nil];

And in the other viewcontroller.h file I would write this to declare the property to get the data

@property (nonatomic) int num;

Now for Swift I have this

let storyBoard : UIStoryboard = UIStoryboard(name: "Main", bundle:nil)
let ansViewController : UIViewController = storyBoard.instantiateViewControllerWithIdentifier("ansView") as UIViewController
ansViewController.num = theNum;
self.presentViewController(ansViewController, animated:true, completion:nil)

and in the other .swift file for the other view controller I declared num by doing

let num: int

I'm pretty sure that isn't the right way to do it because I get an error on this line

ansViewController.num = theNum;

and it says, "UIViewController does not have a member named num" How would I resolve this error and what have I done wrong?

Thanks

lagoon
  • 6,417
  • 6
  • 23
  • 30

1 Answers1

5

The Problem

In Objective C, you've explicitly defined ansViewController as an AnsViewController*, which has the property num.

In your Swift code, though, you've explicitly defined ansViewController as a UIViewController, not an AnsViewController. So, the compiler has no idea if this is actually an AnsViewController, or some other UIViewController subclass, or just a vanilla UIViewController.

Now for the solution.

We're going to try to downcast the returned value as an AnsViewController, then access that property if the downcast succeeds (I'm assuming it always will, but out-of-context from the rest of your code and nibs, I can't be sure).

let storyBoard : UIStoryboard = UIStoryboard(name: "Main", bundle:nil)

// To be safe, let's attempt to downcast the returned value as an AnsViewController
if let ansViewController = storyBoard.instantiateViewControllerWithIdentifier("ansView") as? AnsViewController {
    // We get here if the "as?" succeeds with a non-nil value
    ansViewController.num = theNum;
    self.presentViewController(ansViewController, animated:true, completion:nil)
} else {
    // Out of context, I can't see why this case would (or could) ever happen
}

Now, if you know this will always succeed (from what I can see, the return value of -instantiateWith... is deterministic), then you can be a bit more concise:

let storyBoard : UIStoryboard = UIStoryboard(name: "Main", bundle:nil)

// Force the downcast as an AnsViewController (this could crash at runtime
// if the return value is nil or not an AnsViewController, so again,
// the previous example is safer
let ansViewController = storyBoard.instantiateViewControllerWithIdentifier("ansView") as AnsViewController
ansViewController.num = theNum;
self.presentViewController(ansViewController, animated:true, completion:nil)
Ryan
  • 3,853
  • 4
  • 28
  • 32
  • Thanks! That seems to clear all errors but creates one new one. The line where ansViewController.num = theNum is gives me an error saying CInt is not convertible to Int. I also had to change the part where i declare num to var num : Int = 0 to get rid of errors. Should I have done that? – lagoon Jun 14 '14 at 20:31
  • I think that I am getting that error because I had to use bridgeToObjectiveC().intValue to get the int value from a text field – lagoon Jun 14 '14 at 20:33
  • I'm not sure where theNum is coming from, but try this: `ansViewController.num = Int(theNum)`. – Ryan Jun 14 '14 at 23:15
  • And the reason that works is because Swift is very strict in typing, and does not treat Ints and CInts as interchangeable. You need to init a new Int object from the CInt object. Int(cInt: CInt) is essentially what is being called, an init method that creates an Int from a CInt. – Ryan Jun 14 '14 at 23:17