2012-04-04 5 views
55

Ich habe eine iOS App, die ich als "View-basierte App" in xCode erstellt habe. Ich habe nur einen viewController, aber es wird automatisch angezeigt, und ich sehe keinen Code, der es mit meinem appDelegate verbindet. Ich muss Daten von meinem AppDelegate zu meinem ViewController übergeben, aber ich weiß nicht, wie man das auszieht.Wie greife ich von meinem AppDelegate auf meinen viewController zu? iOS

Meine app delegate.h:

#import <UIKit/UIKit.h> 


@interface AppDelegate : UIResponder <UIApplicationDelegate> 

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

@end 

Auch 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; 
} 

Antwort

90

Sie können darauf zugreifen mit:

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

Wenn Sie die Ansicht hinter einem tabviewcontroller nisten oder Navigationscontroller wird es Ihnen zurückgeben und Sie müssen auf Ihren View-Controller i zugreifen nside of it

+1

Entschuldigung, was ist in diesem Zusammenhang "selbst"? Beziehen Sie sich auf die Eigenschaft "-window" in UIApplicationDelegate? Wenn ja, nur iOS 5+ - nur ein Heads-Up. –

+0

@ConradShultz Ja, es war die UIApplicationDelegate. Das ist wichtig zu wissen, Danke! – utahwithak

+0

Ich bin nicht sicher, ob dies der beste oder einzige Weg ist, aber so habe ich es gewählt und es funktioniert gut. Vielen Dank. – HackyStack

20

Wie wäre es mit guten altmodischen NSNotifications, um eine Nachricht von Ihrem App-Delegierten an alle zu senden (z. B. Ihre Ansicht contorller), dass etwas aktualisiert werden muss? Oder Sie können Key Value Observing verwenden, damit Ihr View-Controller eine Eigenschaft in Ihrem App-Delegaten sehen kann.

+1

+1 ... andere Optionen können zu Spaghetti-Kleber-Code führen. –

+0

NSNotificationCenter ist gut für lose gekoppelte Beziehungen. Wenn dieses Projekt eine einzelne Ansicht aufweist, ist die Delegierung möglicherweise aufgrund der engeren Beziehung ein besserer Ansatz. – jmstone617

+0

@jmstone - Machen Sie den Root-View-Controller zu einem * Delegate * des Anwendungsdelegaten? konzeptionell scheint das möglich zu sein, aber es scheint sicher verwirrend zu sein, vor allem für Neueinsteiger. –

12

Da Sie nur einen View-Controller haben, die generische Art und Weise (unabhängig davon, wie Ihre Anwendung eingerichtet wurde):

UIViewController *vc = [[[UIApplication sharedApplication] keyWindow] rootViewController]; 
0

Wenn Sie die View-basierte Anwendung Vorlage verwendet wird, sollte die einzelnen View-Controller zugänglich sein über eine Eigenschaft in Ihrem App-Delegaten. Es ist derselbe View-Controller, der als Root-View-Controller des Navigations-Controllers eingestellt wird.

Wenn Ihr Projekt aus irgendeinem Grund anders eingerichtet wurde, können Sie den Root-View-Controller des Fensters abrufen, der der Navigationscontroller sein sollte, und dann seinen Top-View-Controller abrufen.

EDIT: Also die Frage ist diese: Mit iOS5 und Storyboards, Apple eine Menge der anfänglichen einrichten abstrahiert hat, dass Sie Zugriff haben zu verwenden (und immer noch zu tun, wenn Sie aus Storyboards entscheiden) . Sie haben die Argumente geändert, die an main() übergeben wurden, und machen mehr vom Setup im Storyboard (das eigentlich nur eine Feder ist). IMHO, das ist zum Teil, um Menschen davon abzuhalten, die AppDelegate mit schweren Operationen zu überlasten, wie es scheint, dass Sie in Ihrem tun. Das AppDelegate ist im Wesentlichen vorhanden, um den Anwendungslebenszyklus zu verwalten. Es ist nicht wirklich dazu gedacht, Methoden auszuführen, die Informationen an Ihre View-Controller weitergeben. Es ist die Aufgabe Ihres View-Controllers, sich wirklich schwer zu machen, um sich mit Daten zu versorgen. Ich würde vorschlagen, den Code in Ihren View-Controller zu verschieben, vielleicht in viewDidLoad. Wenn Sie das Ergebnis des objectForKey-Tests von launchOptions wissen möchten, können Sie ganz einfach eine Eigenschaft in Ihrem AppDelegate erstellen, sagen wir BOOL launchOptionsURLKeyExists, und diese entsprechend einstellen. Dann greifen Sie einfach den Wert dieser Eigenschaft in Ihrem View-Controller. Sie AppDelegate ist bereits ein Singleton, so dass Sie es entweder durch [UIApplication shared] zugreifen können .delegate

EDIT 2: viewWillAppear/viewDidAppear aufgerufen wird, wenn der Blick auf die UIApplicationDidEnterForegroundNotification Benachrichtigung in Ihrem View-Controller hinzugefügt wird und reagieren Sie angemessen, wenn diese Nachricht veröffentlicht wird.

+0

Es gibt keine Eigenschaft und ich weiß nicht, wo es ist, das sage ich hier ... wo ist es eingestellt ??? Hier ist meine AppDelegate.h: #import HackyStack

+0

Ich habe meine Antwort bearbeitet. Ich benutze keine Storyboards, deshalb habe ich vergessen, dass sie jetzt eine Menge von diesen Sachen abstrahieren. – jmstone617

+0

Das Problem ist, wenn die App aktiv wird, muss ich die neue Abfragezeichenfolge ziehen und es zu meinem View-Controller abrufen, aber die einzige Methode, die ich von der App aktiviert wird aktiv ist im App-Delegate (willComeActive oder was auch immer). Ich brauche den View-Controller, um zu erkennen, dass er möglicherweise mit einem anderen Abfrage-String aktiv geworden ist ... – HackyStack

8

Wenn Sie möchten, andere UIViewController zu bekommen, nicht nur die rootViewController:

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

UIStoryboard *storyboard = root.storyboard; 
CustomViewController *vcc =(CustomViewController *) [storyboard instantiateViewControllerWithIdentifier:@"storyBoardID"]; 
+0

sollte dies die richtige antwort –

+0

Glücklich zu sehen, dass meine antwort half ihnen @JenyaKyrmyza:) –

3

Swift Weg, es zu tun, können Sie nennen dies von überall, nicht nur 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 
} 

Seine als Standardfunktion enthalten in:

https://github.com/goktugyil/EZSwiftExtensions

Verwandte Themen