web-dev-qa-db-ja.com

AppDelegateを使用してストーリーボードから作成されたViewControllerにアクセスする

ストーリーボードを使用してiOS5アプリで作業しており、AppDelegateからアクセスしたいViewControllerクラスのメソッドがあります。問題は、このビューコントローラーがストーリーボードのタブバーコントローラーを介してインスタンス化されるため、AppDelegateに必要なメソッドを直接呼び出す方法がないことです...

ViewControllerがAppDelegateと連絡を取るには、次のものを使用するだけです。

MyAppDelegate *appDelegate = (MyAppDelegate *)[[UIApplication sharedApplication] delegate];

すでにインスタンス化されているViewControllerまたはクラスを指す同様の簡単な方法はありますか?

14
Amos

アプリデリゲートからビュー階層をトラバースする必要があります。 AppDelegateUITabBarControllerへの参照を保持していると仮定すると、viewControllersプロパティまたはselectedViewControllerプロパティを使用してViewControllerにアクセスできます。

10
Jerry

ジェリー(上記)のおかげで、私が欲しかったものを手に入れたコードは次のとおりです。

    UINavigationController *navigationController = (UINavigationController *)self.window.rootViewController;
MasterViewController *result;

//check to see if navbar "get" worked
if (navigationController.viewControllers) 

    //look for the nav controller in tab bar views 
    for (UINavigationController *view in navigationController.viewControllers) {

        //when found, do the same thing to find the MasterViewController under the nav controller
        if ([view isKindOfClass:[UINavigationController class]])
            for (UIViewController *view2 in view.viewControllers) 
                if ([view2 isKindOfClass:[MasterViewController class]])                    
                    result = (MasterViewController *) view2;
}
15
Amos

私はおそらく逆にそれをするでしょう。 AppDelegateでregisterViewControllerなどを呼び出すメソッドを作成します。すべてのViewControllerで、名前を付けてそれ自体でメソッドを呼び出します。その後、AppDelegateで、後でやりたいことが何でもできます。あらゆる種類のドリルを行うのは面倒です

AppDelegateで

- (void)registerViewController:(NSString *)name controller:(UIViewController *)controller
{
    if(_viewControllers == nil)
    {
        _viewControllers = [[NSMutableDictionary alloc] init];

    }

    [_viewControllers setObject:controller forKey:name];
}

任意のViewControllerで

- (void)viewDidLoad
{
    [super viewDidLoad];

    AppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
    [appDelegate registerViewController:@"feelings" controller:self];
}

AppDelegateで

XViewController *vc = (XViewController *)[_viewControllers objectForKey:@"X"];
[X startSpinner];

この助けを願っています

BS

10
Billy Sun

ストーリーボードを使用していて、ストーリーボードにviewControllerのインスタンスが必要な場合は、次を使用できます。

UIStoryboard *mystoryboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
id viewcontroller = [mystoryboard instantiateViewControllerWithIdentifier:@"identifier"];

ここで、「識別子」は、「IdentityInspector」の「Identity」セクションにある特定のviewControllerの「storyBoardID」で提供される名前です。

7
infiniteLoop

より良い解決策があります。 window.rootViewController.storyboardを使用して、そのビューのストーリーボードへの参照を取得できます。

6
Steffen Brem

AppDelegateでは、インデックスを使用してUITabBarControllerを介してコントローラーにアクセスできます。

UITabBarController *tabBarController = (UITabBarController *)self.window.rootViewController;
firstViewController = [[tabBarController viewControllers] objectAtIndex:0];
secondViewController = [[tabBarController viewControllers] objectAtIndex:1];
thirdViewController = [[tabBarController viewControllers] objectAtIndex:2];

当然、タブバーの順序を変更すると、これは混乱します。また、階層のより深いコントローラーを探している場合は、もう少し手間をかける必要があります。

2
Pirkka Esko

スイフト

これは、@ infiniteLoopの答えのSwiftバージョンです。

let storyboard = UIStoryboard(name: "Main", bundle: nil)
let myViewController = storyboard.instantiateViewControllerWithIdentifier("identifier") as! MyViewController

ストーリーボード名、ビューコントローラー名、およびビューコントローラー識別子をプロジェクトで使用したものに置き換える必要があります。

関連タスク

1
Suragch