2012-04-05 7 views
2

私はBNRのiOSプログラミングの書籍の第7章で作業しています。章の始めに、前の章のモーションイベントに応答したUIView(HypnosisView)を持つUIViewController(HypnosisViewController)をセットアップしました。親UIViewControllerがRootViewControllerとして設定されていると、UIViewが最初のレスポンダにならない

私はAppDelegate.mファイル内のUIViewControllerを作成します。HypnosisViewControllerで

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

、私はファーストレスポンダになるためにHypnosisViewを設定します。

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

    [view becomeFirstResponder]; 
} 

そしてHypnosisViewに私がYESを返すようにしてください〜にcanBecomeFirstResponder。残念ながら、HypnosisViewは以前のような動きイベントには反応しませんでした。私が最終的に移動したとき、私は興味深い発見をしました。 HypnosisViewControllerをUITabBarControllerに移動すると、HypnosisViewはモーションイベントに応答します。

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]; 

なぜHypnosisViewControllerがRootViewControllerとした最初の応答者になるHypnosisViewませんでしたコードは次のようになりますか?なぜHypnosisViewControllerが別のコントローラの中に配置されたのですか?私はRootViewControllerについて何が分かりませんか?

ありがとうございます!

答えて

2

あなたの質問は非常に適切です。私も同じ本を勉強しており、同じ章に載っています。問題は、UITabBarControllerを使用する前に、HypnosisViewControllerまたはTimeViewControllerを使用することです。次に、AppDelegate.mファイルで[self.window setRootViewController:hvc]または[self.window setRootViewController:tvc]を実行します。その場合、setRootViewControllerメソッドはloadViewメソッドを内部的に呼び出していました。したがって、loadViewが呼び出される必要がある場合は、becomeFirstResponder(コード内のメソッド呼び出しとして内部に存在します)もトリガーされるはずです。したがって、内部的にcanBecomeFirstResponderは と呼ばれるべきです.UITabBarControllerを使用すると、物事が壊れる傾向があります。 loadViewの代わりに '[[self window] setRootViewController:tabBarController];' [tabBarController setViewControllers:viewControllers]; 'によって呼び出されます。つまり、rootViewControllerプロパティ(tabBarControllerに設定されている)はloadViewメソッドを呼び出さないため、 'becomeFirstResponder'は呼び出されません。あなたは '[tabBarController setViewControllers:viewControllers];を通してloadViewが呼び出されると主張するかもしれません。 setViewControllersはroot viewControllerの設定には使用されません。 この問題に直面したら、becomeFirstResponderを明示的に呼び出しました。方法は次のとおりです。 -

@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); 

    } 
関連する問題