如何从推送的控制器获取RootViewController?

bob*_*obo 133 iphone uinavigationcontroller ios

所以,我从RootViewController推送一个视图控制器,如:

[self.navigationController pushViewController:anotherViewController animated:YES] ;

但是,从anotherViewController现在开始,我想再次访问RootViewController.

我尝试着

// (inside anotherViewController now)
///RootViewController *root = (RootViewController*)self.parentViewController ; // No.
// err
RootViewController *root = (RootViewController*)[self.navigationController.viewControllers objectAtIndex:0] ; // YES!! it works

我不确定为什么这样做,我不确定它是否是最好的方法.有人可以评论一个更好的方法从你已经推入RootViewController的navigationController的控制器获取RootViewController,以及我的方式是否可靠?

dul*_*gan 170

Swift版本:

var rootViewController = self.navigationController?.viewControllers.first
Run Code Online (Sandbox Code Playgroud)

ObjectiveC版本:

UIViewController *rootViewController = [self.navigationController.viewControllers firstObject];
Run Code Online (Sandbox Code Playgroud)

self是嵌入在UINavigationController中的UIViewController的实例.


Ben*_*n S 132

使用UINavigationController 的viewControllers属性.示例代码:

// Inside another ViewController
NSArray *viewControllers = self.navigationController.viewControllers;
UIViewController *rootViewController = [viewControllers objectAtIndex:viewControllers.count - 2];
Run Code Online (Sandbox Code Playgroud)

这是获取"后退"视图控制器的标准方法.原因objectAtIndex:0之一是因为您尝试访问的视图控制器也是根视图控制器,如果您在导航中更深入,则后视图将与根视图不同.

  • 上面的代码是错误的.`rootViewController`在它之前缺少`*`,索引应该只是'0`.问题中的代码是正确的:`RootViewController*root =(RootViewController*)[navigationController.viewControllers objectAtIndex:0]` (62认同)
  • :) ty.它似乎仍然是hacky - :)我真的想要一个"官方"成员来完成这项工作,比如self.navigationController.rootViewController,但是唉,没有这样的事情.. (5认同)
  • 同意:上面的代码返回* parent *视图控制器,而不是OP要求的* root *视图控制器。尽管如此,Ben S仍会说他会这样做,只是他指出的还不够。 (2认同)

Jes*_*sse 12

在几乎所有这些答案中提到的同样事物的稍微不那么丑陋的版本:

UIViewController *rootViewController = [[self.navigationController viewControllers] firstObject];
Run Code Online (Sandbox Code Playgroud)

在你的情况下,我可能做的事情如下:

在你的UINavigationController子类中:

- (UIViewController *)rootViewController
{
    return [[self viewControllers] firstObject];
}
Run Code Online (Sandbox Code Playgroud)

然后你可以使用:

UIViewController *rootViewController = [self.navigationController rootViewController];
Run Code Online (Sandbox Code Playgroud)

编辑

OP在评论中要求提供房产.

如果你愿意,你可以通过self.navigationController.rootViewController向标题中添加一个只读属性来访问它:

@property (nonatomic, readonly, weak) UIViewController *rootViewController;
Run Code Online (Sandbox Code Playgroud)


csc*_*sch 8

对于所有对快速扩展感兴趣的人,这就是我现在使用的:

extension UINavigationController {
    var rootViewController : UIViewController? {
        return self.viewControllers.first as? UIViewController
    }
}
Run Code Online (Sandbox Code Playgroud)