我有一个自定义窗口(应该在所有东西(包括键盘)的顶部)上显示一个叠加层内容,类似于您在按下设备中的音量增大/降低按钮时看到的叠加层。

因此,我制作了一个自定义窗口OverlayWindow,到目前为止一切正常,后面的窗口正常接收其事件。但是hitTest:withEvent:被调用了几次,有时甚至返回nil。我想知道这是否正常/正确吗?如果没有,我该如何解决?

// A small (WIDTH_MAX:100) window in the center of the screen. If it matters
const CGSize screenSize = [[UIScreen mainScreen] bounds].size;
const CGRect rect = CGRectMake(((int)(screenSize.width - WIDTH_MAX)*0.5),
       ((int)(screenSize.height - WIDTH_MAX)*0.5), WIDTH_MAX, WIDTH_MAX);
overlayWindow = [[CustomWindow alloc] initWithFrame:rect];
overlayWindow.windowLevel = UIWindowLevelStatusBar; //1000.0
overlayWindow.hidden = NO; // I don't need it to be the key (no makeKeyAndVisible)
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
    // Find the front most window (with the highest window level) and
    // call this method on that window. It should will make the event be
    // forwarded to it

    // Situation1: This method is called twice (or even more, it depend
    // on the number of windows the app has) per event: Why? Is this the
    // *normal* behaviour?

    NSLog(@" ");
    NSLog(@"Point: %@ Event: %p\n", NSStringFromCGPoint(point), event);
    UIView *view = nil;
    if (CGRectContainsPoint(self.bounds, point)) {
        NSLog(@"inside window\n");
        NSArray *wins = [[UIApplication sharedApplication] windows];
        __block UIWindow *frontMostWin = nil;
        [wins enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
            NSLog(@"win: %@\n", obj);
            if ([obj windowLevel] >= [frontMostWin windowLevel] && obj != self) {
                frontMostWin = obj;
            }
        }];
        NSLog(@"frontMostWindow:%@\n finding a new view ...\n", frontMostWin);
        CGPoint p = [frontMostWindow convertPoint:point fromWindow:self];
        view = [frontMostWindow hitTest:p withEvent:event];

       // Situation2: sometimes view is nil here, Is that correct?
    }
    NSLog(@"resultView: %@\n", view);
    return view;
}

编辑:

我也注意到
  • 如果hitTest:withEvent:总是返回nil,它也可以工作。只有当我打电话给overlayWindow.hidden = NO;
  • (如果我调用[overlayWindow makeKeyAndVisible])并不总是返回nil中的hitTest:withEvent:。看起来像一个关键窗口需要正确执行点击测试方法?

  • 我在这里是否缺少有关事件转发的信息?

    最佳答案

    frontMostWindow意味着frontMostWin吗?

    即使我们仅使用一个UIWindow,看起来hitTest:withEvent:也会在其上执行至少2次。所以,我想这很正常。

    您可以在以下位置收到null

    view = [frontMostWindow hitTest:p withEvent:event];
    

    由于以下原因:
  • frontMostWindow本身为null(例如,如果您只有一个窗口)
  • p是ouside frontMostWindow边界(例如,当frontMostWindow是键盘并且您的触摸在其他位置时)
  • frontMostWindow将属性userInteractionEnabled设置为NO;
  • 07-24 09:21