Storyboard正在创建我的DetailViewController的多个实例

时间:2012-11-01 21:28:56

标签: iphone xcode storyboard xib

我开始使用故事板,但我注意到一个非常重要的区别:每次我来回导航时,故事板似乎都在实例化一个新的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时,“position”增加50:所以50,100,150等。

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

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

首次执行segue存储时,属性中的目标viewcontroller(请参阅方法“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;}

1 个答案:

答案 0 :(得分:2)

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

如果你想保留实例,你必须将它保留在你调用它的ViewController中,稍后再使用它。检查此问题是否为example

修改

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

在界面中为viewcontroller创建一个属性,比如myViewController

在prepareForSegue方法中保留viewcontroller:

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

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

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

- (BOOL)shouldPerformSegueWithIdentifier:(NSString *)identifier sender:(id)sender {
    if([self myViewController] != nil){
        [[self navigationController] pushViewController:[self myViewController] animated:YES];
        return NO;
    }else{
        return YES;
    }
}