我开始使用故事板,但我注意到一个非常重要的区别:每次我来回导航时,故事板似乎都在实例化一个新的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;}
答案 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;
}
}