意外的零窗口在_UIApplicationHandleEventFromQueueEvent,_windowServerHitTestWindow

我试图在iPad上设置iOS 8的边缘滑动手势,但得到和错误似乎是一个错误。

我有以下代码:

UIScreenEdgePanGestureRecognizer *edgeRecognizer = [[UIScreenEdgePanGestureRecognizer alloc] initWithTarget:self action:@selector(handleRightEdgeSwipe:)]; edgeRecognizer.edges = UIRectEdgeRight; [self.view addGestureRecognizer:edgeRecognizer]; 

然后我处理这个手势:

 -(void)handleRightEdgeSwipe:(UIGestureRecognizer*)sender { //slide in view code here } 

问题是它没有检测到每次正确的边缘滑动。 有时它会多次检测到它。

无论是否检测到,在iPad上滑动右边缘时,总是会在控制台中显示以下信息:

2014-10-07 00:04:40.386 Office日志[1531:500896]意外的nil窗口在_UIApplicationHandleEventFromQueueEvent,_windowServerHitTestWindow:中; 层=>

这个消息是什么意思,我该如何解决这个问题,以便一致地检测到正确的边缘滑动?

我认为这是iOS中的一个错误,我可以在iOS 7或更高版本上确认iPad mini 2和iPad Air,即使在主屏幕上也是如此。

在“左侧风景”(左侧的主页button)中,屏幕外部的“右侧边缘手势”不适用于我。 在主屏幕上自己testing一下。

我在9个月前向苹果公司报告了一个bug,但注意到进一步发生。

更新:

我玩了一下UIWindow初始化,当它比实际大一点的时候,手势就起作用了。 当然这是一个可怕的修复。

 self.window = [UIWindow new]; self.window.rootViewController = [[UIViewController alloc] init]; // Real Size CGRect frame = [UIScreen mainScreen].bounds; // Real Size + 0.000001 self.window.frame = CGRectMake(0, 0, frame.size.width+0.000001, frame.size.height+0.000001); [self.window makeKeyAndVisible]; 

我得到了同样的问题。 我的解决scheme工作正常:只需在您的Windows中设置您的Windows隐藏。

我不明白它为什么起作用,但是它起作用。

编辑1:

我发现了另一个解决scheme,我认为更好,也更易于理解:

把这个代码放在你的appDelegate的willFinishLaunchingWithOptions中:

 - (BOOL)application:(UIApplication *)application willFinishLaunchingWithOptions:(NSDictionary *)launchOptions { CGRect bounds = [[UIScreen mainScreen] bounds]; [self.window setFrame:bounds]; [self.window setBounds:bounds]; return YES; } 

然后,在你的didFinishLaunchingWithOptions上:

 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { // Your codes... self.window.rootViewController = self.navigationController; [self.window makeKeyAndVisible]; return YES; } 

然后你可以设置你的窗口对象隐藏到NO,它应该工作。

我在iPad上testingiPhone应用程序时遇到了问题。 没有模拟器上的问题,如果我编译的应用程序通用和运行在iPad上没有问题。

 unexpected nil window in _UIApplicationHandleEventFromQueueEvent, _windowServerHitTestWindow: <UIClassicWindow: 0x1276065a0; frame = (0 0; 768 1024); userInteractionEnabled = NO; gestureRecognizers = <NSArray: 0x1740557e0>; layer = <UIWindowLayer: 0x17403fd80>> 

也许帧报错了? (frame =(0 0; 768 1024))

iOS 8有一个错误,即在纵向上下(顶部主页button)或左侧横向(左侧主页button)模式下,在iPad右侧边缘的任何触摸都无法通过正确的视图testing。

解决的办法是将UIWindow到正确的右侧。

 @implementation FixedWindow - (UIView*)hitTest:(CGPoint)point withEvent:(UIEvent*)event { UIView* hit = [super hitTest:point withEvent:event]; if (!hit && point.x >= CGRectGetMaxX(self.bounds)) hit = [super hitTest:CGPointMake(point.x - 0.5, point.y) withEvent:event]; return hit; } @end 

通过window属性将窗口附加到您的应用程序委托。

 @implementation AppDelegate - (UIWindow*)window { if (!_window) _window = [[IVWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; return _window; } @end 

在肖像和风景右模式中,我已经确认右边缘的触摸始终距离边缘至less0.5px,而不是边缘,所以此修补程序应该类似于此。

扩大窗口框架

请注意, 萤火虫的修复也将工作,即稍微扩大窗框,以包括右侧。 然而:

  • 如果在application:willFinishLaunchingWithOptions:application:didFinishLaunchingWithOptions:执行此操作,则您的视图层次结构不会调整为新框架的大小,而右边缘的触摸将无法通过层次结构。
  • 如果旋转设备,窗口可能无法正确对中。 这会导致涂抹或碰撞界面元素略微。

IOS 7:

iOS 7有一个类似的错误,即命中testing也失败,但有一个非零结果和未旋转的几何。 此修补程序应该可以在iOS 7和8上使用:

 @implementation FixedWindow - (UIView*)hitTest:(CGPoint)point withEvent:(UIEvent*)event { UIView* hit = [super hitTest:point withEvent:event]; if (!hit || hit == self) { CGRect bounds = self.bounds; hit = [super hitTest:CGPointMake(MIN(MAX(point.x, CGRectGetMinX(bounds) + 0.5), CGRectGetMaxX(bounds) - 0.5), MIN(MAX(point.y, CGRectGetMinY(bounds) + 0.5), CGRectGetMaxY(bounds) - 0.5)) withEvent:event]; } return hit; } @end 

一个可能的解决办法是删除或注释掉隐藏状态栏的代码,如果你有。 我正在拉我的头发来解决这个问题,我只能根据我的观点来重现它。 看来,如果你隐藏状态栏,你不能拖下今天的部件/通知中心(你可以付出一些努力)。

 /* <- add this - (BOOL)prefersStatusBarHidden { return YES; } add this -> */ 

将您的部署设置为8.x或更高,将启动屏幕设置为您的主要xib。

完成!

这可能是晚了,但有些人可能仍然需要它,通常原因是你没有提供正确尺寸的启动图像或启动屏幕和/或主界面没有设置到你自己的故事板在通用>部署信息