web-dev-qa-db-ja.com

appDelegateからviewControllerにアクセスするにはどうすればよいですか? iOS

XCodeで「ビューベースのアプリ」として作成したiOSアプリがあります。 viewControllerは1つしかありませんが、自動的に表示され、それをappDelegateに関連付けるコードは表示されません。 appDelegateからviewControllerにデータを渡す必要がありますが、それを取得する方法がわかりません。

私のアプリdelegate.h:

#import <UIKit/UIKit.h>


@interface AppDelegate : UIResponder <UIApplicationDelegate>

@property (strong, nonatomic) UIWindow *window;
@property (strong, nonatomic) NSDictionary *queryStrings;

@end

また、appDidFinishLoadingWithOptions:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    // Override point for customization after application launch.
    [[JMC sharedInstance] configureJiraConnect:@"https://cmsmech.atlassian.net/"           projectKey:@"WTUPLOAD" apiKey:@"7fc060e1-a795-4135-89c6-a7e8e64c4b13"];

    if ([launchOptions objectForKey:UIApplicationLaunchOptionsURLKey] != nil) {
        NSURL *url = [launchOptions objectForKey: UIApplicationLaunchOptionsURLKey];
        NSLog(@"url received: %@", url);
        NSLog(@"query string: %@", [url query]);
        NSLog(@"Host: %@", [url Host]);
        NSLog(@"url path: %@", [url path]);
        queryStrings = [self parseQueryString:[url query]];
        NSLog(@"query dictionary: %@", queryStrings);
    }
    else {
        queryStrings = [self parseQueryString:@"wtID=nil"];
    }

    return YES;
}
62
HackyStack

次の方法でアクセスできます。

MyViewController* mainController = (MyViewController*)  self.window.rootViewController;

TabViewControllerまたはNavigation Controllerの背後にビューをネストしている場合、それが返され、その中のView Controllerにアクセスする必要があります

101
utahwithak

古き良き時代の NSNotifications を使用して、アプリのデリゲートから、何かを更新する必要があることを聞いている人(ビューコントローラーなど)にメッセージを送信してみませんか?または、 Key Value Observing を使用して、View Controllerがアプリデリゲートのプロパティを監視できるようにします。

20

ビューコントローラーは1つしかないため、一般的な方法(アプリのセットアップ方法とは無関係):

UIViewController *vc = [[[UIApplication sharedApplication] keyWindow] rootViewController];
12
Conrad Shultz

UIViewControllerだけでなく、他のrootViewControllerを取得する場合:

UIWindow *window=[UIApplication sharedApplication].keyWindow;
UIViewController *root = [window rootViewController];

UIStoryboard *storyboard = root.storyboard;
CustomViewController *vcc =(CustomViewController *) [storyboard instantiateViewControllerWithIdentifier:@"storyBoardID"];
9
Arben Pnishi

それを行うための迅速な方法は、単に委任するだけでなく、どこからでもこれを呼び出すことができます:

/// EZSwiftExtensions - Gives you the VC on top so you can easily Push your popups
public var topMostVC: UIViewController? {
    var presentedVC = UIApplication.sharedApplication().keyWindow?.rootViewController
    while let pVC = presentedVC?.presentedViewController {
        presentedVC = pVC
    }

    if presentedVC == nil {
        print("EZSwiftExtensions Error: You don't have any views set. You may be calling them in viewDidLoad. Try viewDidAppear instead.")
    }
    return presentedVC
}

以下に標準機能として含まれています。

https://github.com/goktugyil/EZSwiftExtensions

6
Esqarrouth

ビューベースのアプリケーションテンプレートを使用した場合は、アプリデリゲートのプロパティを介して単一のView Controllerにアクセスできる必要があります。 Navigation ControllerのルートView Controllerとして設定されるのと同じView Controllerです。

何らかの理由でプロジェクトのセットアップが異なる場合は、ウィンドウのルートビューコントローラー(ナビゲーションコントローラー)を取得してから、そのトップビューコントローラーを取得できます。

EDIT:問題はこれです:iOS5とストーリーボードでは、Appleは抽象化されています以前にアクセスしていた多くの初期設定(そして、ストーリーボードからオプトアウトした場合でも実行されます。)main()に渡される引数を変更し、ストーリーボードでさらに設定を行います(これは私見、これは、あなたがあなたの中で行っているように、人々が重い操作でAppDelegateに過負荷をかけないようにするための一部です。 View Controllerに情報を渡すメソッドを実行しますデータを提供するために大変なことをするのはView Controllerの仕事です実際にはViewDidLoadなどのView Controllerにコードを移動することをお勧めしますあなたがやっているように見えるlaunchOptions objectForKeyテストの結果を知っていれば、非常に簡単にAppDelegateにプロパティを作成することができます、たとえばBOOL launchOptionsURL KeyExists、および適切に設定します。次に、View Controllerでこのプロパティの値を取得します。 AppDelegateはすでにシングルトンであるため、[UIApplication sharedApplication] .delegateからアクセスできます。

編集2:ビューがView ControllerのUIApplicationDidEnterForegroundNotification通知に追加されるとviewWillAppear/viewDidAppearが呼び出され、そのメッセージが投稿されます。

0
jmstone617