从另一个 UIViewController 推送一个 UIViewController - 如何?
Posted
技术标签:
【中文标题】从另一个 UIViewController 推送一个 UIViewController - 如何?【英文标题】:Pushing a UIViewController from another UIViewController - How to? 【发布时间】:2012-12-12 18:49:08 【问题描述】:我有一个 UIViewController 子类(比如 BBB),它继承自已经编写的自定义 UIViewController 类(比如 AAA)。 BBB 类中有一个 UITableView,当用户点击 UITableView 的任何单元格时,我想推送另一个 UIViewController 类(比如 CCC)。
所以,我尝试在 BBB 的tableView: didSelectRowAtIndexPath:
方法中推送 CCC 控制器。
我的代码是,
CCC *ccc = [[CCC alloc] init];
[self.navigationController pushViewController:ccc animated:YES];
[ccc release];
点击单元格时没有任何反应,所以我通过以下代码检查了BBB类的导航控制器。
if (self.navigationController == nil)
NSLog(@"Navigation controller is nil");
消息打印成功 :) 所以,我尝试为导航控制器分配一些东西,但运气不好,它是一个只读属性。
然后我尝试通过将 ccc 分配为 rootviewcontroller 来创建本地 UINavigationController,然后尝试推送该本地导航控制器。它会抛出一个异常“不支持多次推送同一个视图控制器实例”。
我的问题是,
是否可以找到导航控制器在 AAA 类中获得 nil 值的位置?我没有在我的 BBB 类中将导航控制器设为 nil,并且我发现在 AAA 类中是否有任何类似“self.navigationController = nil”的语句。但没有什么是那样的。
如何推送CCC类?
谢谢
【问题讨论】:
你的窗口的根视图控制器是什么?是AAA还是BBB,还是别的什么?你是用storyboard还是xib,还是用代码做所有事情? 我的根视图控制器是另一个控制器(比如 DDD)。我只是通过代码来完成这一切。 【参考方案1】:将它放入您的应用委托中,您的代码的第一个版本应该可以工作。
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
[self.window makeKeyAndVisible];
AAA *aaa = [[AAA alloc] init];
self.window.rootViewController = [[UINavigationController alloc] initWithRootViewController: aaa];
[self.window makeKeyAndVisible];
return YES;
【讨论】:
在我的 AppDelegate 方法中有太多对 self.window.rootViewController 的赋值。我想知道为什么 presentModalViewController: 方法可以正常工作的概念?为什么不 pushViewController? UIViewController.navigationController 的文档说“视图控制器层次结构中最近的祖先是导航控制器。(只读)”如果层次结构中没有导航控制器 - 意味着你没有添加一个 - 它将为零,并且您在其上调用的所有内容都不起作用。因此,如果您正在执行 [self.navigationController pushViewController:vc],它将无法正常工作。将导航控制器设置为根视图控制器。然后将您的其他 viewControllers 添加到其中,并设置它们的属性“self.navigationController”并且 pushViewController 将起作用。【参考方案2】:要正确设置self.navigationController
属性,您必须使用[[UINavigationController alloc] initWithRootViewController: aaa]
创建一个UINavigationController
。然后,无论您当前要添加 aaa 的任何位置(splitViewController 或 UIWindow 等),都应使用您创建的导航控制器。
例如,如果您使用代码设置视图,请在您的应用委托中:
AAA *aaa = [[AAA alloc] init];
UINavigationController *root = [[UINavigationController alloc] initWithRootViewController: aaa];
UIWindow *window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
[window makeKeyAndVisible];
window.rootViewController = root;
现在,aaa.navigationController
将指向 root
,因此您可以执行原始帖子中的操作:[self.navigationController pushViewController: bbb animated: YES];
【讨论】:
我的根视图控制器是另一个类。假设该类为 DDD,我创建该类的一个实例,说 ddd,然后按照您所说的方式尝试。它抛出了同样的错误:( @Confused 更新了帖子。您可以像我的示例中那样将 DDD 添加到导航控制器吗? Sou 会有一个包含 ddd 的导航控制器,然后它推送 aaa,然后它可以推送 bbb? 再次测试,当我点击表格单元格时,它显示了 AAA 控制器(但没有显示我在 CCC 类中定义的内容)。即使我提到 YES 的动画属性,过渡也没有任何动画。 嗨,问题是,当我从 DDD 类中呈现 BBB 类时,我只是呈现 BBB 的实例而没有导航控制器。所以导航控制器设置为零,我无法从 BBB 推送 CCC。谢谢你的时间.. :)以上是关于从另一个 UIViewController 推送一个 UIViewController - 如何?的主要内容,如果未能解决你的问题,请参考以下文章
从另一个 UIViewController 呈现 UIViewController
如何从另一个 UIViewController 触发 UITabBarController 的一个 UIViewController?