Objective c 在收到通知后导航到特定的UIViewController

Objective c 在收到通知后导航到特定的UIViewController,objective-c,ios,uiviewcontroller,uinavigationcontroller,Objective C,Ios,Uiviewcontroller,Uinavigationcontroller,我正在开发一个iOS应用程序,它使用UINavigationController处理UIViewController对象的层次结构: MenuViewController | |-ListOfAnimalsViewController | |-AnimalDetailsViewController | |-ListOfPlantsViewController | |-PlantDetailsViewController 应用程序接收带有特定动物或

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

MenuViewController
  |
  |-ListOfAnimalsViewController
    |
    |-AnimalDetailsViewController
  |
  |-ListOfPlantsViewController
    |
    |-PlantDetailsViewController
应用程序接收带有特定动物或植物信息的本地
NSNotification
对象。触摸通知时的通常行为是打开应用程序并加载层次结构中的第一个视图控制器

是否有一种方法可以通过编程导航到层次结构中深层的
UIViewController
实例


编辑:我不是要求将控制器推入导航堆栈,而是要求同时推入以前的控制器,即我希望保留上面的导航模式。

如果您知道类的名称,可以使用以下代码进行导航

NSString *className = @"viewControllerName";

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

我认为您必须发明自己的机制来遵循导航顺序,因为iOS视图控制器的静态定义中没有定义顺序。(Segues似乎尽其所能接近,但这并不十分接近。)

如果我必须为一个具有未知深度的层次结构控制器做这件事,我会考虑创建一个与路径一起工作的超类,类似于网络路由。它将有一个方法,例如

displaytextcontrolleronpath:(NSString*)path
。一个
MenuViewController
是一个
RoutingController
子类,它将收到一个类似于“ListofAnimalViewController.AnimalDetailsViewController”的路径,去掉第一个path元素,实例化它(它是另一个
RoutingController
子类),然后将它发送到“AnimalDetailsViewController”


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

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

只需按下要显示的ViewController,这样您将只创建一个ViewController。在每个可作为通知结果按下的ViewController(以及下面的所有ViewController)中,覆盖后退按钮的行为。使用NSStringFromClass,检查navigationController的ViewController属性(如果之前的ViewController是您期望的)。如果没有,请创建一个NSMutableArray作为ViewController的副本,创建所需的ViewController,并将其插入阵列中倒数第二个点。然后通过调用navigationController上的setViewControllers:animated:方法替换整个堆栈,使用可变数组,animated NO。最后执行pop。同样,您一次只创建一个ViewController,以保持最佳性能


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

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

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;

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

这将把
myClass
推送到导航堆栈中,而不推上一个控制器。我想尊重导航顺序好的,那么你可以在firstViewController的viewDidLoad中推到第二个view controller,以防你得到动物或植物信息。你的解决方案看起来很有趣,并且避免使用segues。我试试看,让你知道