敲击键盘时触发 hotTest
Posted
技术标签:
【中文标题】敲击键盘时触发 hotTest【英文标题】:hitTest fires when UIKeyboard is tapped 【发布时间】: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 会以这种方式搞砸吗?谢谢。
【问题讨论】:
【参考方案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 属性,注册了UIKeyboardDidShowNotification
和UIKeyboardDidHideNotification
,并添加了:
- (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];
【讨论】:
以上是关于敲击键盘时触发 hotTest的主要内容,如果未能解决你的问题,请参考以下文章