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