HypnosisViewController

HypnosisViewController

我正在研究BNR的iOS编程书的第7章,但遇到了一个问题。在本章的开头,我设置了一个UIViewController(HypnosisViewController)和一个UIView(HypnosisView),以响应上一章中的运动事件。

我在AppDelegate.m文件中创建UIViewController:

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

在HypnosisViewController中,我将HypnosisView设置为第一响应者:
- (void)loadView
{
    // Create a view
    CGRect frame = [[UIScreen mainScreen] bounds];
    HypnosisView *view = [[HypnosisView alloc] initWithFrame:frame];
    [self setView:view];

    [view becomeFirstResponder];
}

并且在HypnosisView中,确保将canBecomeFirstResponder返回YES。不幸的是,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缺少什么?

谢谢!

最佳答案

您的问题很贴切。我也在学习同一本书,并且在同一章上。问题是,在使用UITabBarController之前,我们将使用HypnosisViewController或TimeViewController。然后,我们将在AppDelegate.m文件中执行[self.window setRootViewController:hvc]或[self.window setRootViewController:tvc]。在这种情况下,setRootViewController方法在内部调用loadView方法。因此,如果应该调用loadView,则应该触发beginFirstResponder(作为方法调用驻留在其内部)。所以在内部canBecomeFirstResponder应该被调用
现在,当我们使用UITabBarController时,事情往往会破裂。发生的是不是通过[[[self window] setRootViewController:tabBarController];”调用loadView。的代码行,通过“[tabBarController setViewControllers:viewControllers];”来调用。因此,最重要的是rootViewController属性(当设置为tabBarController时)不会调用loadView方法,因此不会调用'becomeFirstResponder'。您可能会争辩说loadView确实是通过'[tabBarController setViewControllers:viewControllers];'调用的但是setViewControllers不用于设置根viewController。
遇到此问题时,我明确调用了成为FirstResponder的电话。这是如何做:-

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

    }

10-02 06:44