Assign a value to a controller property in Swift

2019-06-26 04:01发布

问题:

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

回答1:

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)