我刚刚将iOS 8更新发送到我的填字游戏应用程序Four Down,并且已经开始接收报告,它进入无法输入答案的状态,因为点击键盘会解除它而不是输入字母。
经过一些调查后,只要应用程序进入后台,它就会可靠地进入此状态,然后再次变为活动状态。退出应用程序并重新启动它可以解决问题,直到下一次从后台恢复为止。
当问题发生时,看起来事物以错误的顺序堆叠以进行触摸检测(但不是视觉上),因为键盘下方的视觉接收触摸。我相信问题的iOS 8具体。
在尝试诊断问题时,我已经将UIApplication子类化并覆盖了sendEvent,以便我可以检查发送的事件。当问题发生时,事件被分配给错误的UIWindow。这是它工作时的事件:
2014-10-04 07:56:57.998 four-down[95709:8557144] <UITouchesEvent: 0x7fe838f07350> timestamp: 1.29014e+06 touches: {(
<UITouch: 0x7fe83a11abf0> phase: Began tap count: 1 window: <UITextEffectsWindow: 0x7fe838d549e0; frame = (0 0; 320 568); opaque = NO; gestureRecognizers = <NSArray: 0x7fe838d556d0>; layer = <UIWindowLayer: 0x7fe838d54ea0>> view: <UIKeyboardLayoutStar: 0x7fe838da6a90; frame = (0 0; 320 216); opaque = NO; layer = <CALayer: 0x7fe838db3cc0>> location in window: {243, 388.5} previous location in window: {243, 388.5} location in view: {243, 36.5} previous location in view: {243, 36.5}
)}
以下是无法正常工作的事件:
2014-10-04 07:58:08.952 four-down[95709:8557144] <UITouchesEvent: 0x7fe838f07350> timestamp: 1.29021e+06 touches: {(
<UITouch: 0x7fe83a5c91a0> phase: Began tap count: 1 window: <UIWindow: 0x7fe83a33f3f0; frame = (0 0; 320 568); gestureRecognizers = <NSArray: 0x7fe83a340010>; layer = <UIWindowLayer: 0x7fe83a304160>> view: <CrosswordInteractiveView: 0x7fe83a555920; frame = (0 65; 310 310); gestureRecognizers = <NSArray: 0x7fe83a54d4e0>; layer = <CALayer: 0x7fe83a544df0>> location in window: {241.5, 379} previous location in window: {241.5, 379} location in view: {236.5, 250} previous location in view: {236.5, 250}
)}
注意两个事件的不同窗口。 UITextEffectsWindow是包含键盘的窗口,UIWindow是主应用程序窗口。我检查了每个窗口上的windowLevel属性。两种情况都是一样的:键盘窗口为1.0,主应用程序窗口为0.0。
如果有的话,我做错了什么?鉴于它适用于iOS 7,感觉就像一个iOS错误,但也许我应该调用一个新的iOS 8 API?如果没有,我会欢迎有关解决方法的建议
答案 0 :(得分:2)
我向Apple提交了一份雷达(18546966)。他们把它作为18406902的副本关闭了。显然,18406902已经关闭,但这就是我所拥有的所有信息。不知道该修补程序将在哪个版本的iOS中。它可以在iOS 9测试版中修复 - 我还没有测试过它。
与此同时,我想出了以下解决方法,它已经停止了错误报告:
- (UIView*) hitTest:(CGPoint) point withEvent:(UIEvent*) event {
UIView* hitView = [super hitTest:point withEvent:event];
if (!hitView) {
UIWindow* keyboardWindow = [self findKeyboardWindow];
if (keyboardWindow) {
UIView* viewInKeyboardWindow = [keyboardWindow hitTest:point withEvent:event];
if (!viewInKeyboardWindow) {
[self resignFirstResponder];
} else {
return viewInKeyboardWindow;
}
} else {
[self resignFirstResponder];
}
}
return hitView;
}
- (UIWindow*) findKeyboardWindow {
NSArray* windows = [UIApplication sharedApplication].windows;
if (windows.count == 2) {
for (UIWindow* candidate in windows) {
if (candidate != self.window) {
return candidate;
}
}
}
return nil;
}