使用故事板在导航期间维护uiviewcontroller的状态

时间:2013-02-04 15:24:28

标签: objective-c uiviewcontroller storyboard state

在任何iPhone应用程序中,请考虑以下序列(VC = ViewController):

  1. 显示VC-A ...用户点击按钮加载VC-B
  2. VC-B现在被推送并显示...用户将滑块从0移动到5 ...然后点击返回导航栏
  3. 弹出VC-B,显示VC-A ...用户再次点击按钮加载VC-B
  4. 按下并显示VC-B ......但滑块返回0
  5. 这是因为上面步骤2中的VC-B实例与步骤4中的VC-B实例不同,因此状态丢失。为了避免这种情况,我可以将VC-B变为singelton,或者在某处保留对VC-B的强引用,并重用它而不是创建新实例。

    当我从笔尖加载VC时,这种逻辑运行良好,因为我会在代码中手动创建VC的实例。使用故事板,这不起作用,因为它是自动创建实例的segue。那我怎样才能确保我重新使用我的VC呢?

    我尝试了以下技巧来维持singelton:

    
    - (id) initWithCoder:(NSCoder *)aDecoder{
        if(instance==nil){
            NSLog(@"LMHomeViewController init called");
            instance = [super initWithCoder:aDecoder];
            super.screenType = [NSNumber numberWithInt:home_screen];
        }
        return instance;
    }
    

    但是我遇到了运行时错误:

    Terminating app due to uncaught exception 'NSGenericException', reason: 'This coder requires that replaced objects be returned from initWithCoder:'
    

    这里有什么建议吗?我感兴趣的是当用户在导航树中来回时保持VC的状态。

    注意:在我的情况下,状态是一个UIWebView,因此无法保持其状态。

1 个答案:

答案 0 :(得分:0)

这可能是使用NSUserDefaults的情况 - 在viewWillAppear上读取状态,在viewWillDisappear上写出,(以及其他适当的地方)

无论如何,在模型中而不是在视图层次结构中持久存在更好的MVC。因此,如果不是NSUserDefaults,请考虑只需要存储状态数据的单例。

另一个想法。如果你想要保持viewController对象 - 不要使用storyboard segue。在房产中保留强大的参考资料并使用

  [self.navigationController pushViewController:self.persistingViewController];

persistingViewController访问器可以第一次懒惰地实例化viewController。只要保留引用,就可以重用:

  - (UIViewController*) persistingViewController
  {
     if (!_persistingViewController) {
       UIStoryboard *story = [UIStoryboard storyboardWithName:@"MainStoryBoard" bundle:nil];
     _persistingViewController = [story instantiateViewControllerWithIdentifier:@"myViewController"];

   }

   return self.persistingViewController

}