如何从我的 appDelegate 访问我的 viewController?IOS
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10015567/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do I access my viewController from my appDelegate? iOS
提问by HackyStack
I have an iOS app I created as a "view-based app" in xCode. I have only one viewController, but it is displayed automatically, and I see no code that ties it to my appDelegate. I need to pass data from my appDelegate to my viewController, but don't know how to pull that off.
我有一个在 xCode 中创建为“基于视图的应用程序”的 iOS 应用程序。我只有一个 viewController,但它会自动显示,而且我没有看到将它与我的 appDelegate 相关联的代码。我需要将数据从我的 appDelegate 传递到我的 viewController,但不知道如何实现它。
My app delegate.h:
我的应用程序委托.h:
#import <UIKit/UIKit.h>
@interface AppDelegate : UIResponder <UIApplicationDelegate>
@property (strong, nonatomic) UIWindow *window;
@property (strong, nonatomic) NSDictionary *queryStrings;
@end
Also, appDidFinishLoadingWithOptions:
此外,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;
}
回答by utahwithak
You can access it with:
您可以通过以下方式访问它:
MyViewController* mainController = (MyViewController*) self.window.rootViewController;
If you are nesting your view behind a tabviewcontroller or navigation controller it will return that to you and you will need to access your view controller inside of it
如果您将视图嵌套在 tabviewcontroller 或导航控制器后面,它将返回给您,您将需要访问其中的视图控制器
回答by Michael Dautermann
How about using good old fashioned NSNotificationsto send a message from your app delegate to anyone listening (e.g. your view contorller) that something needs to be updated? or you can use Key Value Observingso your view controller can be watching some property in your app delegate.
如何使用老式的NSNotifications从您的应用程序委托向任何收听的人(例如您的视图控制器)发送需要更新的消息?或者您可以使用Key Value Observing以便您的视图控制器可以监视应用程序委托中的某些属性。
回答by Conrad Shultz
Since you only have one view controller, the generic way (independent of how your app was set up):
由于您只有一个视图控制器,因此通用方式(与您的应用程序的设置方式无关):
UIViewController *vc = [[[UIApplication sharedApplication] keyWindow] rootViewController];
回答by Arben Pnishi
If you want to get any other UIViewController
, not just the rootViewController
:
如果你想得到任何其他的UIViewController
,而不仅仅是rootViewController
:
UIWindow *window=[UIApplication sharedApplication].keyWindow;
UIViewController *root = [window rootViewController];
UIStoryboard *storyboard = root.storyboard;
CustomViewController *vcc =(CustomViewController *) [storyboard instantiateViewControllerWithIdentifier:@"storyBoardID"];
回答by Esqarrouth
Swift way to do it, you can call this from anywhere, not just appdelegate:
快速的方式来做到这一点,你可以从任何地方调用它,而不仅仅是 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
}
Its included as a standard function in:
它作为标准功能包含在:
回答by jmstone617
If you used the View-Based Application template, the single view controller should be accessible via a property in your app delegate. It's the same view controller that gets set as the root view controller of the navigation controller.
如果您使用基于视图的应用程序模板,则应可通过应用程序委托中的属性访问单个视图控制器。它与被设置为导航控制器的根视图控制器的视图控制器相同。
If for some reason your project was set up differently, you can get the root view controller of the window, which should be the navigation controller, and then get its top view controller.
如果由于某种原因您的项目设置不同,您可以获取窗口的根视图控制器,它应该是导航控制器,然后获取其顶视图控制器。
EDIT:So the issue is this: With iOS5 and storyboards, Apple has abstracted a lot of the initial set up that you used to have access to (and still do if you opt out of storyboards). They've altered the arguments passed to main() and do more of the set up in the storyboard (which is really just a nib). IMHO, this is in part to keep people from overloading the AppDelegate with heavy operations, like it appears you are doing in yours. The AppDelegate, in essence, exists to manage the Application lifecycle. It's not really meant to be performing methods that hand off information to your view controllers. It's your view controller's job, really, to do the heavy lifting to provide itself with data. I would suggest moving the code into your view controller, perhaps in viewDidLoad. If you need to know the result of the launchOptions objectForKey test it appears you're doing, you could very simply create a property on your AppDelegate, say BOOL launchOptionsURLKeyExists, and set it appropriately. Then you just grab the value of this property in your view controller. You AppDelegate is already a singleton, so you can access it either by [UIApplication sharedApplication].delegate
编辑:所以问题是这样的:对于 iOS5 和故事板,Apple 已经抽象了许多您曾经可以访问的初始设置(如果您选择退出故事板,仍然可以访问)。他们改变了传递给 main() 的参数,并在故事板中做更多的设置(这实际上只是一个笔尖)。恕我直言,这部分是为了防止人们通过繁重的操作使 AppDelegate 过载,就像您在自己的操作中所做的那样。AppDelegate 本质上是为了管理应用程序生命周期而存在的。它并不是真的要执行将信息传递给视图控制器的方法。实际上,您的视图控制器的工作是完成繁重的工作来为自己提供数据。我建议将代码移动到您的视图控制器中,也许在 viewDidLoad 中。如果您需要知道您正在执行的 launchOptions objectForKey 测试的结果,您可以非常简单地在您的 AppDelegate 上创建一个属性,例如 BOOL launchOptionsURLKeyExists,并对其进行适当的设置。然后你只需在你的视图控制器中获取这个属性的值。你 AppDelegate 已经是一个单例了,所以你可以通过 [UIApplication sharedApplication].delegate 访问它
EDIT 2:viewWillAppear/viewDidAppear gets called when the view is added to the UIApplicationDidEnterForegroundNotification notification in your view controller and respond appropriately when that message is posted.
编辑 2:viewWillAppear/viewDidAppear 在视图添加到视图控制器中的 UIApplicationDidEnterForegroundNotification 通知时被调用,并在发布该消息时做出适当的响应。