如何从推控制器获取RootViewController?
所以,我从RootViewController推入一个视图控制器,如:
[self.navigationController pushViewController:anotherViewController animated:YES];
但是,从anotherViewController
现在,我想再次访问RootViewController。
我尝试着
//(在另一个ViewController里面) /// RootViewController * root =(RootViewController *)self.parentViewController; //不 // 呃 RootViewController * root =(RootViewController *)[self.navigationController.viewControllers objectAtIndex:0]; //是的 有用
我不知道为什么这个工作,我不知道如果它是最好的办法做到这一点。 有人可以评论一个更好的方式来从你已经推入到RootViewController的导航控制器的控制器中获取RootViewController,以及我做的方式是否可靠?
使用UINavigationController的viewControllers属性。 示例代码:
// Inside another ViewController NSArray *viewControllers = self.navigationController.viewControllers; UIViewController *rootViewController = [viewControllers objectAtIndex:viewControllers.count - 2];
这是获得“后退”视图控制器的标准方式。 objectAtIndex:0
的原因是因为你试图访问的视图控制器也是根视图控制器,如果你在导航中更深入,后视图将不会和根视图一样。
Swift版本:
var rootViewController = self.navigationController?.viewControllers.first
ObjectiveC版本:
UIViewController *rootViewController = [self.navigationController.viewControllers firstObject];
其中self是UINavigationController中embedded的UIViewController的一个实例。
几乎所有这些答案中提到的同一事物的略微不那么丑陋的版本:
UIViewController *rootViewController = [[self.navigationController viewControllers] firstObject];
在你的情况下,我可能会做这样的事情:
在你的UINavigationController子类中 :
- (UIViewController *)rootViewController { return [[self viewControllers] firstObject]; }
那么你可以使用:
UIViewController *rootViewController = [self.navigationController rootViewController];
编辑
OP在评论中询问了一处房产。
如果你喜欢,你可以通过像self.navigationController.rootViewController
这样的东西来访问它,只需要在你的头文件中添加一个readonly属性即可:
@property (nonatomic, readonly, weak) UIViewController *rootViewController;
对于所有对快速扩展感兴趣的人,这就是我现在使用的:
extension UINavigationController { var rootViewController : UIViewController? { return self.viewControllers.first as? UIViewController } }
作为@ dulgan答案的补充,使用firstObject
over objectAtIndex:0
总是一个好办法,因为如果数组中没有对象,则第一个返回nil,后一个则抛出exception。
UIViewController *rootViewController = self.navigationController.viewControllers.firstObject;
或者,创build一个名为UINavigationController+Additions
的类别,并在其中定义您的方法将是一个很大的优势。
@interface UINavigationController (Additions) - (UIViewController *)rootViewController; @end @implementation UINavigationController (Additions) - (UIViewController *)rootViewController { return self.viewControllers.firstObject; } @end
如何问UIApplication的 单身人士的keyWindow ,并从该UIWindow要求的根视图控制器(它的rootViewController属性):
UIViewController root = [[[UIApplication sharedApplication] keyWindow] rootViewController];
在这里,我想出了从任何地方导航到根的通用方法。
-
您可以使用这个类创build一个新的Class文件,以便在项目的任何地方都可以访问它:
import UIKit class SharedControllers { static func navigateToRoot(viewController: UIViewController) { var nc = viewController.navigationController // If this is a normal view with NavigationController, then we just pop to root. if nc != nil { nc?.popToRootViewControllerAnimated(true) return } // Most likely we are in Modal view, so we will need to search for a view with NavigationController. let vc = viewController.presentingViewController if nc == nil { nc = viewController.presentingViewController?.navigationController } if nc == nil { nc = viewController.parentViewController?.navigationController } if vc is UINavigationController && nc == nil { nc = vc as? UINavigationController } if nc != nil { viewController.dismissViewControllerAnimated(false, completion: { nc?.popToRootViewControllerAnimated(true) }) } } }
-
您的项目中的任何地方使用:
{ ... SharedControllers.navigateToRoot(self) ... }