从另一个 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?

有没有办法查看当前 UIViewController 是不是从另一个 UIViewController 的解雇中出现

从其他项目推送 ViewController 时出错

从另一个 UIViewController 刷新表

如何从另一个 UIViewController 更改分段控件标题(设置)