unexpected nil window in _UIApplicationHandleEventFromQueueEvent, _windowServerHitTestWindow

后端 未结 7 706
执念已碎
执念已碎 2020-12-16 01:18

I am trying to set up an edge swipe gesture in iOS 8 on iPad but getting and error that seems like a bug.

I have the following code:

    UIScreenEdge         


        
7条回答
  •  一向
    一向 (楼主)
    2020-12-16 01:49

    iOS 8 has a bug where any touch that begins exactly on an iPad right edge when in Portrait Upside-Down (home button on top) or Landscape Left (home button on left) mode fails to be hit tested to the correct view.

    The fix is to subclass UIWindow to hit test the right side properly.

    @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
    

    Attach the window to your application delegate via the window property.

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

    In Portrait and Landscape Right modes, I've confirmed that right edge touches are always at least 0.5px from the edge instead of exactly on the edge, so this fix should work in analogy to that.

    Expanding the window frame

    Note that firebug's fix will also work i.e. slightly expanding the window frame to include the right side. However:

    • If you do this at application:willFinishLaunchingWithOptions: or application:didFinishLaunchingWithOptions:, your view hierarchy doesn't get resized to the new frame and right edge touches won't make it through the hierarchy.
    • If you rotate the device, the window may not be centered correctly. This leads to either smearing or bumping interface elements slightly.

    iOS 7:

    iOS 7 has a similar bug in that the hit test also fails but with a non-nil result and unrotated geometry. This fix should work with both iOS 7 and 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
    

提交回复
热议问题