2

我开始使用故事板,但注意到一个非常显着的区别:每次我来回导航时,故事板似乎都在实例化一个新的 ViewController。示例:我基于 Master-Detail 模板创建了两个新的 Xcode 项目。在案例 1 中,我使用情节提要,在案例 2 中,我使用 .xib。

通常我会期望这些行为相同,但他们没有!

在这两个 DetailViewController.m 中,我都添加了以下方法:

-(void)viewDidAppear:(BOOL)animated{
if (xposition ==0) {
    xposition=50;
}else{
    xposition = xposition+50;
}
NSLog(@"xposition update %d", xposition);

}

(我还在标题中将 xposition 声明为“int”实例变量):

当我运行 Storyboard 版本并点击“+”并导航进出 DetailViewController 时,我的 NSLog 语句不断给我“xposition update 50”。

相比之下,对于 .xib 版本,我得到了预期的行为,每次我导航进出 DetailViewController 时,“位置”都会增加 50:所以 50、100、150 等。

如何修复 Storyboard 以使其行为方式与基于 .xib 的版本相同。具体来说,我只想实例化 DetailViewController 一次。

编辑:回答我自己的问题。我得到了一些帮助,并想发布对我有用的答案。

当您第一次执行 segue 时,将目标视图控制器存储在属性中(请参阅方法“PrepareForSegue”。我的 VC 称为 MyViewController)

然后创建名为“shouldPerformSegueWithIdentifier”的委托方法,并使用它来拦截 segue 并为所有后续 segue 手动呈现存储的 ViewController。

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
UIViewController *destination = segue.destinationViewController;
NSLog(@"identifier = %@", [segue identifier]);
if([[segue identifier] isEqualToString:@"mySegue"]) {
    self.myViewController = (MyViewController*)destination;
    NSLog(@"Saving myViewController for later use.");
}}

- (BOOL)shouldPerformSegueWithIdentifier:(NSString *)identifier sender:(id)sender {
if([identifier isEqualToString:@"mySegue"]) {
    if(self.myViewController != nil) {
        NSLog(@"Using the saved myViewController.");
        [self.navigationController pushViewController:self.myViewController animated:YES];
        return NO;
    }else {
        return YES;
    }
}
return YES;}
4

1 回答 1

2

当您来回导航时,您的故事板会从您的 DetailViewController 中弹出。因为它不会被其他任何东西保留,所以它会被释放,这是正常的行为。

如果您想保留该实例,则必须将其保留在您从中调用它的 ViewController 中,并稍后再次使用它。检查此问题以获取示例

编辑:

我认为你解决了这个问题,但这里有一个例子:

在您的界面中为您的视图控制器创建一个属性,例如myViewController

在 prepareForSegue 方法中保留视图控制器:

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
    [self setMyViewController:[segue destinationViewController]]; 
}

这不会泄漏内存,您的示例在某些情况下可能会泄漏。在此处查看本指南。

下次执行序列时,检查属性是否已设置,如果已设置,请使用它:

- (BOOL)shouldPerformSegueWithIdentifier:(NSString *)identifier sender:(id)sender {
    if([self myViewController] != nil){
        [[self navigationController] pushViewController:[self myViewController] animated:YES];
        return NO;
    }else{
        return YES;
    }
}
于 2012-11-01T21:57:19.893 回答