2012-04-05 4 views
2

ich auf Kapitel 7 arbeiten von iOS-Programmierung Buch BNR und ich habe auf ein Problem stoßen. Zu Beginn des Kapitels habe ich einen UIViewController (HypnosisViewController) mit einem UIView (HypnosisView) eingerichtet, der auf Bewegungsereignisse im vorherigen Kapitel reagiert hat.UIView hat sich nicht First Responder, wenn Eltern UIViewController als RootViewController gesetzt

ich die UIViewController in der AppDelegate.m-Datei zu erstellen:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 
{ 
    ... 
    HypnosisViewController *hvc = [[HypnosisViewController alloc] init]; 
    [[self window] setRootViewController:hvc]; 
    ... 
} 

Im HypnosisViewController, habe ich HypnosisView Ersthelfer werden:

- (void)loadView 
{ 
    // Create a view 
    CGRect frame = [[UIScreen mainScreen] bounds]; 
    HypnosisView *view = [[HypnosisView alloc] initWithFrame:frame]; 
    [self setView:view]; 

    [view becomeFirstResponder]; 
} 

Und in HypnosisView ich sicherstellen, dass JA zurück zu canBecomeFirstResponder. Leider reagierte die HypnosisView nicht wie zuvor auf Bewegungsereignisse. Als ich schließlich weiterzog, machte ich eine interessante Entdeckung. Wenn ich HypnosisViewController in einen UITabBarController verschiebe, reagiert HypnosisView auf Bewegungsereignisse. Der Code sieht etwa so aus:

HypnosisViewController *hvc = [[HypnosisViewController alloc] init]; 

UITabBarController *tabBarController = [[UITabBarController alloc] init]; 

NSArray *viewControllers = [NSArray arrayWithObjects:hvc, <insert more objs here>, nil]; 
[tabBarController setViewControllers:viewControllers]; 
[[self window] setRootViewController:tabBarController]; 

Warum nicht HypnosisView Ersthelfer, wenn HypnosisViewController als RootViewController gesetzt wurde? Warum begann es zu funktionieren, sobald HypnosisViewController in einem anderen Controller installiert wurde? Was fehlt mir an RootViewController?

Danke!

Antwort

2

Ihre Frage ist sehr leicht. Ich studiere auch das gleiche Buch und bin im selben Kapitel. Die Sache ist, dass wir, bevor wir UITabBarController verwendet haben, entweder HypnosisViewController oder TimeViewController verwenden würden. Und dann würden wir [self.window setRootViewController: hvc] oder [self.window setRootViewController: tvc] in der Datei AppDelegate.m machen. In diesem Fall hat die Methode setRootViewController die Methode loadView intern aufgerufen. Wenn also loadView aufgerufen werden soll, dann sollte auch findReshresponder (das sich als Methodenaufruf in Ihrem Code befindet) ausgelöst werden. So intern canBecomeFirstResponder sollte aufgerufen werden Jetzt, wenn wir UITabBarController verwenden, neigen die Dinge zu brechen. Was passiert, ist der Aufruf von loadView über '[[self window] setRootViewController: tabBarController];' Zeile des Codes, es wird durch 'aufgerufen [tabBarController setViewControllers: viewControllers];'. Die Grundlinie ist also, dass die rootViewController-Eigenschaft (wenn sie auf tabBarController gesetzt ist) die loadView-Methode nicht aufruft und daher 'werdenFirstResponder' nicht aufgerufen wird. Sie können argumentieren, dass loadView über '[tabBarController setViewControllers: viewControllers] aufgerufen wird;' setViewControllers wird jedoch nicht zum Festlegen von root viewController verwendet. Als ich mit diesem Problem konfrontiert wurde, machte ich einen expliziten Aufruf zum FirstResponder. Hier ist, wie: -

@implementation HypnoTimeAppDelegate 

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions //method of UIApplicationDelegate protocol 
{ 
    NSLog(@"lets begin"); 
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; 
    // Override point for customization after application launch. 
    HypnosisViewController *viewController= [[HypnosisViewController alloc] init]; 

    TimeViewController *viewController2= [[TimeViewController alloc] init]; 


    NSLog(@"view controllers are done initializing!"); 

    UITabBarController *tabBarController= [[UITabBarController alloc] init]; 
    NSArray *viewControllers= [NSArray arrayWithObjects:viewController,viewController2, nil]; 

    [tabBarController setViewControllers:viewControllers];//loadView of HypnosisViewController gets called internally since the 'app view' isn't going to load from a XIB file but from 'HypnosisView.m'.loadView method of TimeViewController loads its own view from the XIB file. 

    [self.window setRootViewController:tabBarController]; 

    self.window.backgroundColor = [UIColor whiteColor]; 

    [self.window makeKeyAndVisible]; 

    return YES; 
} 

@implementation HypnosisViewController 

-(void)loadView{ 

    NSLog(@"HypnosisView loading..."); 
    HypnosisView *myView= [[HypnosisView alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; 
    self.view= myView; 
    [self configureFirstResponder];//configuring first responder 
} 



-(void) configureFirstResponder{ 
     BOOL viewDidBecomeFirstResponder= [self.view becomeFirstResponder]; 
     NSLog(@"Is First Responder set as HypnosisView? %i",viewDidBecomeFirstResponder); 

    }