UINavigationController 子类和推送 Segue

Posted

技术标签:

【中文标题】UINavigationController 子类和推送 Segue【英文标题】:UINavigation Controller subclass and push Segues 【发布时间】:2014-03-20 06:09:47 【问题描述】:

我已经找了一段时间了,它可能有一个简单的答案: 根据 Apple 文档,在 ios6 之后,我们可以继承 UINavigationController。当它阻止任何不是 UINavigationController 的东西时,我们如何从标识符执行 segue。主要是:

uncaught exception 'NSGenericException', reason: 'Could not find a 
navigation controllerfor segue 'profileSegue'. Push segues can only 
be used when the source controller is managed by an instance of 
UINavigationController.

我正在使用 JaSidePanels,我的中心面板(导航)需要成为委托的子类,因为左侧面板上有一个菜单,我想在单击时切换视图。

@interface CenterViewController : UINavigationController <MenuDelegate>

基本上,由于这个对象在运行时是一个CenterViewController,有没有办法将它转换为它的超类?我已经尝试过 [self superclass] 但这没有用(同样的错误)。

我需要在 CenterViewController 中调用此代码。是否可以将其移至 UINavigationController?

- (void)viewDidLoad


RootViewController *rootViewController = (RootViewController *)[[[[UIApplication sharedApplication] delegate] window] rootViewController];
MenuViewController *leftViewController = (MenuViewController *)rootViewController.leftPanel;

// Store a reference to the center view controller in the left view controller's delegate property
leftViewController.menuDelegate = self;

[super viewDidLoad];


- (void) MenuItemSelected: (NSString*) item

    if ([item isEqualToString:@"Home"]) 
        //These would throw the error since we're not technically a "UINavigationController"
        //[self performSegueWithIdentifier: @"mapViewController" sender: nil];
     else if ([item isEqualToString:@"Profile"]) 
        //[self performSegueWithIdentifier: @"profileSegue" sender: self];
    

编辑: 更多信息与图片。 我很好奇导航控制器应该如何与侧面板一起工作。我查看了许多其他的侧面板插件,这里有一个例子。即使它有效,为什么它有 2 个导航控制器?

这是我们当前的设置:

所以基本上,我想将一个新的 VC 推到现有的 NavVC 的意义上是不是在考虑这个错误?按下菜单按钮时推送新的 NavVC 会更好吗?当我们从 Maps 视图进入子视图时会发生什么。可以通过滑动访问菜单吗?

【问题讨论】:

你的代理需要是 UINavigationController 吗?您不能创建另一个对象作为委托,然后允许该对象切换视图吗? 我担心 JaSidePanels 是否会损坏,因为我需要在“CenterViewController”中设置委托。如果我将委托切换回 UINavigation 控制器,我将如何设置它?我会用更多信息更新问题。 【参考方案1】:

如果您仔细查看该消息,您会发现您的问题不是由子类化UINavigationController 引起的,而是因为您正在针对您的(子类化)UINavigationController 执行 segue。 Push segues 针对嵌入在UINavigationController 中或由UINavigationController 管理的UIViewController 执行,然后系统通过视图控制器的navigationController 属性找到管理UINavigationController 以执行推送。

你收到的消息说

...Push segues 只能 当源控制器由一个实例管理时使用 UINavigationController

在您的情况下,源控制器 UINavigationController 的一个实例,它不是 UINavigationController 管理的。

您还没有确切说明您的应用导航是如何工作的,但我怀疑 UINavigationController 无论如何都不是正确的工具。如果您使用侧边菜单允许用户以随机方式选择中心内容(即用户可以选择第一个选项,然后选择第五个,然后返回到第一个),那么您可能应该只是有一个中心视图您呈现选定的视图。将视图推送到 UINavigationController 最终会得到大量视图“堆栈”,除非您在推送新视图控制器之前弹出当前视图控制器,这更加复杂,而不是您正在寻找的视觉效果。

您仍然可以实现“推送”样式转换,但您需要使用自定义转场。如果是我,如果用户选择的菜单项比当前选项更靠近顶部,我可能会从左侧推送,如果新项目比当前选项更靠近底部,我可能会从右侧推送,但我又在做关于您的应用导航如何工作的假设。

更新

是的,我认为您在更新问题的部分中处于正确的轨道上。导航控制器用于以分层方式导航一系列相关视图 - 想想设置应用程序 - 您选择“常规”或“墙纸”或其他任何内容 - 然后每个控制器都有一系列您可以浏览的视图;上下堆叠。

在您的应用中,主页、配置文件和设置都应该是导航控制器。您的根视图将只是一个视图。您的菜单将选择在根视图中显示哪个视图控制器 - 这就像一个标签栏控制器,除了您的菜单取代了标签栏。

您可以在您的 appDelegate 中分配您的主页、配置文件和设置视图控制器,并将它们存储到 appDelegate 的属性中。然后你可以使用这样的东西:

- (void) MenuItemSelected: (NSString*) item

    myappDelegate *app=(myappDelegate *)[UIApplication sharedApplication].delegate;


    [delegate.currentViewController removeFromParentViewController]; 
    UIViewController *newController;
    if ([item isEqualToString:@"Home"]) 
        newController=app.homeViewController;

     else if ([item isEqualToString:@"Profile"]) 
        newController=app.profileViewController;
    

    if (app.currentViewController != newController)
    
        [app.currentViewController removeFromParentViewController];
        [app.rootViewController addChildViewController:newController];
        app.currentViewController = newController;

【讨论】:

感谢您的回复 Paul,我已经用图片和更多问题更新了问题。我可能在想 NavVC 的错误。你能解释一下我哪里出错了吗? 我已根据您提供的新信息更新了我的答案 另外,当我更新答案时我有点着急,因为我不得不离开,但我刚刚意识到我应该使用 segue 调用来选择视图而不是添加子视图 - 但是想法是一样的

以上是关于UINavigationController 子类和推送 Segue的主要内容,如果未能解决你的问题,请参考以下文章

自定义 UINavigationController UIToolbar 子类

UINavigationController 子类和推送 Segue

iphone UIViewController 基子类未在 UINavigationController 中显示视图

以编程方式在 UINavigationController 中设置 UINavigationBar 的自定义子类

UINavigationController 子类未按预期调用 willShowViewController

来自 tableViewController 子类的 UINavigationController pushViewController