66

我有一个我在 xCode 中创建为“基于视图的应用程序”的 iOS 应用程序。我只有一个 viewController,但它会自动显示,而且我看不到将它与我的 appDelegate 关联的代码。我需要将数据从我的 appDelegate 传递到我的 viewController,但不知道如何实现。

我的应用委托.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;
}
4

6 回答 6

108

您可以通过以下方式访问它:

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

如果您将视图嵌套在 tabviewcontroller 或导航控制器后面,它将返回给您,您需要访问其中的视图控制器

于 2012-04-04T16:45:08.257 回答
22

使用老式的NSNotifications将消息从您的应用程序代理发送给任何监听(例如您的视图控制器)需要更新的东西怎么样?或者您可以使用Key Value Observing,以便您的视图控制器可以在您的应用程序委托中查看某些属性。

于 2012-04-04T16:45:48.757 回答
12

由于您只有一个视图控制器,因此通用方式(与您的应用程序的设置方式无关):

UIViewController *vc = [[[UIApplication sharedApplication] keyWindow] rootViewController];
于 2012-04-04T16:46:34.307 回答
9

如果您想获得其他任何东西UIViewController,而不仅仅是rootViewController

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

UIStoryboard *storyboard = root.storyboard;
CustomViewController *vcc =(CustomViewController *) [storyboard instantiateViewControllerWithIdentifier:@"storyBoardID"];
于 2015-04-21T13:25:00.470 回答
6

快速的方式来做到这一点,你可以从任何地方调用它,而不仅仅是 appdelegate:

/// 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

于 2015-11-24T04:15:58.767 回答
0

如果您使用基于视图的应用程序模板,则应该可以通过应用程序委托中的属性访问单个视图控制器。它与设置为导航控制器的根视图控制器的视图控制器相同。

如果由于某种原因您的项目设置不同,您可以获取窗口的根视图控制器,它应该是导航控制器,然后获取其顶部视图控制器。

编辑: 所以问题是这样的:在 iOS5 和 Storyboard 中,Apple 已经抽象了很多你曾经可以访问的初始设置(如果你选择不使用 storyboard,仍然可以访问)。他们更改了传递给 main() 的参数,并在情节提要中进行了更多设置(实际上只是一个 nib)。恕我直言,这部分是为了防止人们使用繁重的操作使 AppDelegate 超载,就像您正在做的那样。AppDelegate 本质上是为了管理应用程序生命周期而存在的。它并不是真的要执行将信息传递给视图控制器的方法。实际上,为自己提供数据是您的视图控制器的工作。我建议将代码移动到您的视图控制器中,也许在 viewDidLoad 中。如果您需要知道您正在执行的launchOptions objectForKey 测试的结果,您可以非常简单地在您的AppDelegate 上创建一个属性,例如BOOL launchOptionsURLKeyExists,并进行适当的设置。然后,您只需在视图控制器中获取此属性的值。您的 AppDelegate 已经是一个单例,因此您可以通过 [UIApplication sharedApplication].delegate 访问它

编辑 2: viewWillAppear/viewDidAppear 在视图添加到视图控制器中的 UIApplicationDidEnterForegroundNotification 通知时被调用,并在发布该消息时适当响应。

于 2012-04-04T16:56:47.093 回答