0

假设我在 ViewControllerA 上有一个 UILabel,在 ViewControllerB 上有一个 UITextField。我想去 ViewControllerB 并输入文本,然后按一个按钮返回 ViewControllerA。UILabel 现在应该读取在 UITextField 中输入的任何内容。

通过使用 NSUserDefaults 和委托,我能够完成上述任务。我正在使用故事板来做到这一点。我的问题是关于故事板中使用的转场。

似乎在使用委托时,我必须使用代码进出情节提要,而不是在视觉上将视图控制器与 segue 连接以传输数据。这是我按下 ViewController A 上的按钮时的代码:

- (IBAction)pressFirstButton:(id)sender {
UIStoryboard* sb = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil];
RBViewController2 *vc2 = [sb  instantiateViewControllerWithIdentifier:@"ViewController2"];
[vc2 setDelegate:self];
[self presentViewController:vc2 animated:YES completion:NULL];
}  

当将数据从 ViewControllerB 传递回 ViewControllerA 时,我这样做:

- (IBAction)buttonSegueBackTo1:(id)sender {
NSString *sendThis = self.textFieldVC2.text;
[self.delegate passTextFieldInput:sendThis];
[self dismissViewControllerAnimated:YES completion:NULL];
}

视图控制器之间没有划线,一切正常。如果我不编写相同的代码并在 segue 中绘制,数据将不会向后传递。但是,当我尝试使用 NSUserDefaults 传递这样的数据时,我不必编写代码来进出视图控制器。相反,我可以简单地将视图控制器与绘制的 segue 连接起来。奇怪的是,如果我在手动编码视图控制器(不绘制 segue)时尝试使用 NSUserDefaults 传递数据,则数据不会传输。

我在想也许不是在 -(IBAction) pressFirstButton:(id) sender 方法中编写代码,而是应该将代码放在 prepareForSegue 方法中。

我的问题是为什么绘制的segues有时会导致数据丢失?是否必须在没有抽签的情况下完成所有委派?如果 NSUserDefaults 需要 segues 正确传输并且委派需要代码正确传输,那么如果我有一个需要两者的视图,似乎 NSUserDefaults 将胜过委派 b/c 正在使用的手动 segue “重置”视图并且只有 NSUserDefaults 数据遗迹。

4

2 回答 2

1

普通转场(除了展开转场)总是创建新的视图控制器。因此,如果您使用非展开 segue 以外的任何方法返回到 A,那么您实际上并不是在“返回”,而是在创建一个新的 ViewControllerA。在您演示的情况下,通常不会使用展开转场,只是返回一个控制器,但您可以。

这种情况也不是使用用户默认值的好地方。Apple 推荐的方法是使用委托,就像您在问题代码中所做的那样。您展示的方式可能是最好的方式,而不是使用转场返回。不过,您当然可以使用 segue 继续前进,在这种情况下,您将实现 prepareForSegue: 因此您可以将自己设置为委托和/或转发任何数据。

于 2013-02-13T19:30:30.347 回答
1

你的问题有点难以解析,但我想你是在问是否有办法通过 segues 获取传递数据。答案是肯定的,而且比您尝试的解决方法要好得多。

在您的按钮中,您会调用:

[self performSegueWithIdentifier:@"scrollerSegue" sender:self];

这将触发下面的方法,您可以在这里设置目标 viewController 上的数据。您可以在目标 viewController 上设置抽象属性,但不能填充 UIKit 元素(标签、图像视图等),因为它们尚不存在。而是设置属性,然后在viewWillAppear目标 viewController 中,根据需要进行设置。(或者,您可以设置委托,然后调用委托上的方法以根据需要获取数据,而不是传递数据)。

为了取回数据,使用委托并在其上调用方法似乎是 Apple 推荐的做事方式。

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
     if ([[segue identifier] isEqualToString:@"scrollerSegue"])
     {
         ScrollViewController * target = segue.destinationViewController;
         target.assetsArray = self.assetsArray;
         target.delegate = self;
     }
}
于 2013-02-13T19:37:00.070 回答