だから、私はRootViewControllerからView Controllerを次のようにプッシュします:
[self.navigationController pushViewController:anotherViewController animated:YES];
しかし、anotherViewController
から、今、再びRootViewControllerにアクセスしたいです。
私はしようとしています
//(今すぐanotherViewController内) /// RootViewController * root =(RootViewController *)self.parentViewController; // No。 // err RootViewController * root =(RootViewController *)[self.navigationController.viewControllers objectAtIndex:0]; // はい!!できます
なぜこれが機能するのかわからないし、それが最善の方法かどうかもわかりません。 RootViewControllerのnavigationControllerにプッシュしたコントローラからRootViewControllerを取得するより良い方法と、私がやった方法が信頼できるかどうかについて誰かがコメントできますか?
UINavigationControllerの viewControllers プロパティを使用します。サンプルコード:
// Inside another ViewController
NSArray *viewControllers = self.navigationController.viewControllers;
UIViewController *rootViewController = [viewControllers objectAtIndex:viewControllers.count - 2];
これは、「戻る」View Controllerを取得する標準的な方法です。 objectAtIndex:0
が機能する理由は、アクセスしようとしているView Controllerもルートのものであるためです。ナビゲーションを深く行うと、背面ビューはルートビューと同じになりません。
迅速なバージョン:
var rootViewController = self.navigationController?.viewControllers.first
ObjectiveCバージョン:
UIViewController *rootViewController = [self.navigationController.viewControllers firstObject];
Selfは、UINavigationControllerに埋め込まれたUIViewControllerのインスタンスです。
これらの回答のほとんどで言及されている同じものの少しslightlyいバージョン:
UIViewController *rootViewController = [[self.navigationController viewControllers] firstObject];
あなたの場合、私はおそらく次のようなことをします:
INavigationControllerサブクラス内:
- (UIViewController *)rootViewController
{
return [[self viewControllers] firstObject];
}
次に使用できます:
UIViewController *rootViewController = [self.navigationController rootViewController];
編集
OPはコメントでプロパティを要求しました。
必要に応じて、ヘッダーに読み取り専用プロパティを追加するだけで、self.navigationController.rootViewController
などの方法でこれにアクセスできます。
@property (nonatomic, readonly, weak) UIViewController *rootViewController;
Swift拡張機能に興味があるすべての人にとって、これは私が今使用しているものです。
extension UINavigationController {
var rootViewController : UIViewController? {
return self.viewControllers.first as? UIViewController
}
}
@ dulgan's answerへの追加として、firstObject
over objectAtIndex:0
を使用することは常に適切なアプローチです。後者は例外をスローします。
UIViewController *rootViewController = self.navigationController.rootViewController;
または、UINavigationController+Additions
という名前のカテゴリを作成し、その中にメソッドを定義することは大きなプラスになります。
@interface UINavigationController (Additions)
- (UIViewController *)rootViewController;
@end
@implementation UINavigationController (Additions)
- (UIViewController *)rootViewController
{
return self.viewControllers.firstObject;
}
@end
IApplicationsingleton に keyWindow を要求し、そこから IWindow にルートビューコントローラー(its rootViewController property):
UIViewController root = [[[UIApplication sharedApplication] keyWindow] rootViewController];
ここで、あらゆる場所からルートに移動するための普遍的な方法を思いつきました。
プロジェクト内のどこからでもアクセスできるように、このクラスで新しいクラスファイルを作成します。
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)
...
}