【问题标题】:UIView doesn't become First Responder when parent UIViewController is set as RootViewController当父 UIViewController 设置为 RootViewController 时,UIView 不会成为第一响应者
【发布时间】:2012-04-05 21:30:17
【问题描述】:

我正在编写 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 缺少什么?

谢谢!

【问题讨论】:

    标签: ios ios5 uiview uiviewcontroller first-responder


    【解决方案1】:

    你的问题很贴切。我也在学习同一本书,并且在同一章。问题是在我们使用 UITabBarController 之前,我们要么使用 HypnosisViewController 要么使用 TimeViewController。然后我们将在 AppDelegate.m 文件中执行 [self.window setRootViewController:hvc] 或 [self.window setRootViewController:tvc]。在这种情况下,setRootViewController 方法在内部调用 loadView 方法。因此,如果应该调用 loadView ,那么 becomeFirstResponder (根据您的代码作为方法调用驻留在其中)也应该被触发。所以内部 canBecomeFirstResponder 应该被调用 现在,当我们使用 UITabBarController 时,事情往往会破裂。发生的事情不是通过 '[[self window] setRootViewController:tabBarController];' 调用 loadView代码行,它通过'[tabBarController setViewControllers:viewControllers];'调用。所以底线是 rootViewController 属性(当设置为 tabBarController 时)不会调用 loadView 方法,因此不会调用“becomeFirstResponder”。您可能会争辩说 loadView 确实是通过 '[tabBarController setViewControllers:viewControllers];' 调用的但 setViewControllers 不用于设置根视图控制器。 当我遇到这个问题时,我明确地调用了 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);
    
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-02-17
      • 1970-01-01
      • 2013-05-25
      • 1970-01-01
      • 2011-06-02
      相关资源
      最近更新 更多