使用模态视图控制器修改UINavigationController堆栈

时间:2012-04-16 11:44:08

标签: ios uinavigationcontroller modalviewcontroller presentmodalviewcontroller

我有以下环境:

  • 根视图控制器是UINavigationController
  • 可以在导航堆栈上推送许多自定义UIViewControllers
  • 每个自定义控制器可能会也可能不会呈现模态视图控制器
  • 我需要能够以编程方式管理导航堆栈(例如 - 从导航堆栈中删除除根控制器之外的所有控制器,作为对推送通知传递等外部事件的响应)

如果存在由堆栈中任何旧控制器提供的模态视图控制器,那么[navigationController setViewControllers:newControllers animated:animated];的朴素实现显然会失败:

  1. 此模态控制器保持可见
  2. 如果委托模式用于父级< - >模态控制器通信(父级是呈现的模态视图控制器的委托),则模式视图控制器中的任何操作都会导致崩溃,因为委托已经发布
  3. 所以一般的问题是模态控制器生命周期没有绑定到父控制器。我的问题是:

    1. 是否存在管理此类层次结构和安全导航堆栈更改的标准方法?
    2. 如果不是最好的自定义实现?我看到了两种常用方法 - 一种是在代码中明确地解除/取消链接所有模态控制器,更改导航堆栈,另一种是向父视图控制器添加逻辑以直接管理模态控制器生命周期。

3 个答案:

答案 0 :(得分:2)

没有标准方法,因为HIG不鼓励这种行为。即使在推送通知的情况下,除了通过推送,弹出和弹出到根之外,您不应该修改现有堆栈。但是,你所要求的是完全可能的。

您有多种选择,但最好的选择可能是通知。在您的应用委托中使用NSNotificationCenter,让任何感兴趣的视图控制器知道您关于以弹出到您的根视图控制器。在每个模态视图控制器中,注册此通知名称并在收到通知后自行解除。在解除你的模态之后,你可以使用popToRootViewController并避免修改堆栈的混乱。

看看TweetBot,看看他们如何处理推送通知。我相信他们做得很好,他们只是提出了一个新的模态视图控制器。你可以这样做(嵌套的模态演示文稿),所以试验一下,看看你能做什么而不会刺激用户。

答案 1 :(得分:1)

检查此方法: http://developer.apple.com/library/ios/documentation/uikit/reference/UINavigationController_Class/Reference/Reference.html#//apple_ref/occ/instm/UINavigationController/popToRootViewControllerAnimated

此外,模态控制器的模态是有充分理由的 - 将用户的注意力吸引到一个任务或工作单元或任何应用程序所做的事情上。所以,如果你想以编程方式隐藏它并返回导航堆栈中的其他控制器,那么你需要首先处理模态控制器。

答案 2 :(得分:0)

调用[self dismissModalViewControllerAnimated:YES]; from - (void)viewcontroller的viewDidUnload方法。