今天我学会了如何在View Controllers之间传递数据。
我有3个视图控制器,它们都使用Push segues,用户按以下顺序访问它们:SignUp View Controller>验证视图控制器> Pin提交视图控制器
无论如何,今天早些时候我能够成功地将数据从注册视图控制器传递到验证视图控制器。
然后我意识到我需要将SignUp View Controller上生成的一些数据传递给Pin Submit View Controller。我尝试使用正常的prepareForSegue
方法实现,但过去一小时我无法使用它。
所以我感到沮丧,并将其设置为将数据从SignUp View Controller传递到Verification View Controller,然后传递到Pin Submit View Controller。即使验证视图控制器不需要或对我传递的数据有任何用处。
果然它完美无缺!但令人沮丧的是,我不明白为什么我不能只使用我的常规方法并在验证视图控制器甚至不使用数据时将数据从SignUp View Controller直接传递到Pin Submit View Controller
是因为我使用的是prepareForSegue
方法吗?
这是我一直在使用的一个例子。这是我在“发送”View Controller的主文件中的prepareForSegue
实现:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:self {
if ([segue.identifier isEqualToString:@"signupToVerificationSegue"]) {
VerificationViewController *verifyViewController = segue.destinationViewController;
PinSubmitViewController *pinViewController = [[PinSubmitViewController alloc]init];
verifyViewController.uniqueVerificationCode = _uniqueVerificationCode;
verifyViewController.userSubmittedUsername = _userSubmittedUsername;
pinViewController.userSubmittedUsername = _userSubmittedUsername;
}
}
然后这是一个IBAction方法实现,它连接到一个UIButton并负责执行实际的segue,也称为我们在上面实现的prepareForSegue
方法和performSegueWithIdentifier
方法: / p>
- (IBAction)didTapSignup:(id)sender {
NSString *user = [_usernameEntry text];
NSString *pass = [_passwordEntry text];
NSString *email = [_emailEntry text];
self.userSubmittedUsername = user;
int randomCode = arc4random() % 9000 + 1000;
NSString *uniqueVerificationCode = [[NSString alloc]initWithFormat:@"%d", randomCode];
self.uniqueVerificationCode = uniqueVerificationCode;
PinSubmitViewController *pinViewController = [[PinSubmitViewController alloc]init];
pinViewController.userSubmittedUsername = _userSubmittedUsername;
NSLog(@"%@", _userSubmittedUsername);
NSLog(@"%@", user);
NSLog(@"%@", pass);
NSLog(@"%@", email);
NSLog(@"Random 4 Digit Code: %@", uniqueVerificationCode);
if ([user length] < 4 || [pass length] < 4) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Invalid Entry" message:@"Username and Password must both be at least 4 characters long." delegate:self cancelButtonTitle:@"Okay" otherButtonTitles:nil];
[alert show];
} else if ([email length] < 8) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Invalid Entry" message:@"Please enter your email address." delegate:self cancelButtonTitle:@"Okay" otherButtonTitles:nil];
[alert show];
} else {
[_activityIndicator startAnimating];
PFUser *newUser = [PFUser user];
newUser.username = user;
newUser.password = pass;
newUser.email = email;
NSLog(@"SEE IF THE PROPERTY WORKED: %@", self.uniqueVerificationCode);
newUser[@"verificationCode"] = self.uniqueVerificationCode;
[newUser signUpInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
[_activityIndicator stopAnimating];
if (error) {
NSString *errorString = [[error userInfo] objectForKey:@"error"];
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Error" message:errorString delegate:self cancelButtonTitle:@"Okay" otherButtonTitles:nil];
[alert show];
} else {
NSLog(@"No errors in signup process");
UIStoryboardSegue *segue = [[UIStoryboardSegue alloc]init];
[self prepareForSegue:segue sender:self];
[self performSegueWithIdentifier:@"signupToVerificationSegue" sender:self];
}
}];
}
对此有任何帮助,并深入了解为什么我无法以我想要的方式实现这一目标,将不胜感激,谢谢!
答案 0 :(得分:2)
prepareForSegue
方法中真正发生的事情是它通知视图控制器即将执行segue。
因此,您可以使用segue
对象访问destinationViewController,并且可以通过访问属性将一些数据传递给它。
你想要实现的是将数据传递给一些甚至尚未在内存中分配的ViewController。 代码中的这一行:
PinSubmitViewController *pinViewController = [[PinSubmitViewController alloc]init];
将创建一个PinSubmitViewController
的新对象,该对象与推送的segues无关。
因此,您应该将数据传递到VerificationViewController
,然后将其传递给PinSubmitViewController
,或者您可以使用NSUserDefaults
来保存和访问数据(因为我看到的数据并不多)。您也可以使用单身人士。
答案 1 :(得分:1)
您无需在prepareForSegue
方法中创建新的UIViewController。您创建的那个 - PinSubmitViewController
- 在prepareForSegue
方法结束时被取消分配,因为ARC没有看到任何强引用。
在您的情况下,我会通过VerificationViewController
传递数据或使用NSUserDefaults
。
P.S。您也不需要手动调用[self prepareForSegue:segue sender:self]
- 它会在执行segue的过程中自动调用。