【问题标题】:hitTest fires when UIKeyboard is tapped敲击键盘时触发 hotTest
【发布时间】:2011-11-09 23:05:44
【问题描述】:

我正在尝试修复涉及 UIView hitTest:withEvent: 在 UIKeyboard 上进行触摸时在我的视图上调用的错误,但仅在应用程序已在后台运行后调用。

它发生在我的应用程序中,具有复杂的视图层次结构,因此我在一个只有 2 个视图的应用程序中重现了它:

  • 1 UIView 768x1024(全屏)
  • 1 UITextView 200x200 在全屏视图的上半部分

行为如下:

  • 点击文本视图会导致全屏视图的 hitTest 方法触发,文本字段成为第一响应者,然后键盘按预期显示。敲击键盘按键效果很好。
  • 现在关闭键盘。
  • 将应用程序发送到后台。
  • 然后恢复应用。
  • 再次使 textview 成为第一响应者。问题来了,现在当点击键盘上的键时,全屏视图的 hitTest 方法正在触发。

我在 iOS 5 iPad 2 上看到了这一点。但仅在设备上,从不在模拟器中。知道为什么 hitTesting 会以这种方式搞砸吗?谢谢。

【问题讨论】:

    标签: ios ios5 hittest first-responder


    【解决方案1】:

    上面描述的问题似乎是由于键盘的 UIWindow 卡在了错误的状态。确保键盘窗口的 hidden 属性设置为 YES(即使它已经是 YES)为我解决了这个问题。这可以在您的 UIApplicationDelegate 类中完成:

    - (void)applicationWillEnterForeground:(UIApplication *)application {
        // The keyboard sometimes disables interaction when the app enters the 
        // background due to an iOS bug. This brings it back to normal.
        for (UIWindow *testWindow in [UIApplication sharedApplication].windows) {
            if (!testWindow.opaque && [NSStringFromClass(testWindow.class) hasPrefix:@"UIText"]) {
                BOOL wasHidden = testWindow.hidden;
                testWindow.hidden = YES;
    
                if (!wasHidden) {
                    testWindow.hidden = NO;
                }
    
                break;
            }
        }
    }
    

    键盘窗口的类名,至少在带有标准美式键盘的 iOS 5 中,是 UITextEffectsWindow。像往常一样,依赖未记录的类名不是一个好主意,但对于特定于操作系统的错误,它适用于我的目的。可以有任意数量的窗口,包括根应用程序窗口、键盘、警报以及您的应用程序或其他框架添加的其他窗口,所以不要太具体。

    【讨论】:

      【解决方案2】:

      这里有同样的问题。只有当我回家并返回应用程序时才会发生这种情况。 在第一次新运行时不会发生。

      而且和iOS5也有关系。

      【讨论】:

      • 感谢您的确认,我将向 Apple 提交错误报告。如果其他人也可以打开重复的错误,我将不胜感激。
      • 当然。只是为了分享更多发现: * iOS 5.0.1 上的相同问题 * 模拟器上不会出现 * iPhone 和 iPod 设备上也会出现同样的问题 * 在 iOS 5 之前的 SDK 上构建的版本中不会出现
      • 就我而言,我通过使用另一个委托而不是 hitTest 解决了这个问题。这个成功了: - (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView;是的,它是一个被 tableview 调用的滚动视图委托。
      • 今天早上我遇到了这个错误:|感谢您确保错误。
      【解决方案3】:

      我遇到了同样的问题,我的解决方法是听 UIKeyboardDidShowNotification 和 UIKeyboardDidHideNotification,使用 UIKeyboardFrameEndUserInfoKey 计算键盘高度,然后在我的 hitTest:withEvent: 方法中,我会看到点击是在键盘“区域”还是不是。

      【讨论】:

      • 是的,我也必须做这样的事情,但这绝对不理想。
      【解决方案4】:

      只是为了扩展@enzo-tran 的答案,这就是我最终要做的事情:我在我的 UIView 子类中添加了一个 keyboardRect 属性,注册了UIKeyboardDidShowNotificationUIKeyboardDidHideNotification,并添加了:

      - (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
        if (CGRectContainsPoint([self keyboardRect], point)) {
          // Ignore      
        } else {
          ...
        }
      }
      
      - (void)keyboardDidShow:(NSNotification *)notif {
          CGRect keyboardRect;
      
          [[[notif userInfo] valueForKey:UIKeyboardFrameEndUserInfoKey] getValue:&keyboardRect];
          keyboardRect = [self convertRect:keyboardRect fromView:nil];
      
          [self setKeyboardRect:keyboardRect];
      }
      
      - (void)keyboardDidHide:(NSNotification *)notif {
          [self setKeyboardRect:CGRectZero];
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2019-02-18
        • 1970-01-01
        • 1970-01-01
        • 2015-10-30
        • 2017-11-21
        • 2011-08-16
        • 2021-11-08
        相关资源
        最近更新 更多