【问题标题】:Navigate to a specific UIViewController after receiving a NSNotification收到 NSNotification 后导航到特定的 UIViewController
【发布时间】:2012-11-22 13:25:46
【问题描述】:

我正在开发一个 iOS 应用程序,它使用 UINavigationController 处理 UIViewController 对象的层次结构:

MenuViewController
  |
  |-ListOfAnimalsViewController
    |
    |-AnimalDetailsViewController
  |
  |-ListOfPlantsViewController
    |
    |-PlantDetailsViewController

应用程序接收带有某种动物或植物信息的本地NSNotification 对象。当您触摸通知时,通常的行为是打开应用程序并加载层次结构中的第一个视图控制器。

有没有办法以编程方式导航到层次结构深处的 UIViewController 实例?

编辑:我不是要求将控制器推入导航堆栈,而是要求将以前的控制器也推入,即我想保留上面的导航架构。

【问题讨论】:

    标签: objective-c ios uiviewcontroller uinavigationcontroller


    【解决方案1】:

    我将不得不不同意 Suresh。虽然此解决方案可能适用于像这样的简单情况,即您只有 1 个以前的 ViewController,但如果您想添加第 10 个 ViewController 并保留整个层次结构怎么办?首先,您必须通过每个 ViewController 传递您想要显示的最后一条数据(在本例中为植物或动物),并且您将一次创建 10 个 ViewController。当前 ViewController 和第 10 个之间的转换远非无缝,性能会很糟糕。也不需要去创建自己的导航系统,不需要让事情变得更复杂,因为这个问题并不太难。

    只需推送您要显示的 ViewController,这样您就只会创建 1 个 ViewController。在每个可以作为通知的结果推送的 ViewController 中(以及所有下面的),覆盖后退按钮的行为。如果之前的 ViewController 是您所期望的,请使用 NSStringFromClass 检查 navigationController 的 viewControllers 属性。如果没有,请创建一个 NSMutableArray 作为 viewControllers 的副本,创建您期望的 ViewController 并将其插入到数组中倒数第二个位置。然后通过使用可变数组调用导航控制器上的 setViewControllers:animated: 方法来替换整个堆栈,动画 NO。最后做流行音乐。同样,您一次只创建 1 个 ViewController,保持最佳性能。

    我现在无法发布代码,因为我在 iPad 上,但如果你需要它,尽管问,当我有一个真正的键盘时,我会添加一个示例。

    【讨论】:

    • 您的解决方案似乎很有趣,并且避免使用 segues。我会试一试让你知道
    【解决方案2】:

    如果你知道类名,可以使用下面的代码进行导航。

    NSString *className = @"viewControllerName";
    
        UIViewController* myClass = (UIViewController*)[[NSClassFromString(className) alloc] init];
    [self.navigationController pushViewController:myClass animated:YES];
    

    【讨论】:

    • 这会将myClass 推入导航堆栈,而不会推入前一个控制器。我要尊重导航顺序
    • 好的,那么您可以在firstViewController的viewDidLoad处推送到第二个视图控制器,以防您获得动物或植物信息。
    【解决方案3】:

    我认为您必须发明自己的机制来遵循导航顺序,因为 iOS 视图控制器的静态定义中没有定义顺序的内容。 (Segues 似乎已经很接近了,但并不是很接近。)

    如果我必须为具有未知深度的视图控制器层次结构执行此操作,我会考虑创建一个使用路径的超类,有点像网络路由。它会有一个方法,例如displayNextControllerOnPath:(NSString *)path。作为RoutingController 子类的MenuViewController 将接收类似@"ListOfAnimalsViewController.AnimalDetailsViewController" 的路径,剥离第一个路径元素,实例化它(它是另一个RoutingController 子类),然后发送@"AnimalDetailsViewController"。

    其他细节包括知道何时停止以及可能将对象或字典作为负载传递给最后一个控制器以用作内容。

    【讨论】:

      【解决方案4】:

      我会用以下方式重建堆栈:

      MenuViewController *menuController = [[MenuViewController alloc] init];
      ListOfAnimalsViewController *listController = [[ListOfAnimalsViewController alloc] init];
      AnimalDetailsViewController *detailsController = [[AnimalDetailsViewController alloc] init];
      UINavigationController *navigationController = [[UINavigationController alloc] init];
      [navigationController setViewControllers:@[menuController, listController, detailsController]];
      self.window.rootViewController = navigationController;
      

      您可能需要根据您的实现设置一些属性。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-10-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-06-19
        • 2012-06-11
        • 1970-01-01
        相关资源
        最近更新 更多