iphone - -[自定义窗口 HitTest :withEvent:] implementation to forward events

标签 iphone objective-c ios events uiwindow

我有一个自定义窗口(应该在所有内容之上,包括键盘)来显示覆盖物,类似于您在设备中按音量增大/减小按钮时看到的覆盖物。

所以我制作了一个自定义窗口 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;
}

编辑:

我也注意到了

  1. 如果 hitTest:withEvent: 总是返回 nil 它也有效。这仅在我调用 overlayWindow.hidden = NO;

  2. 时发生
  3. 如果我调用 [overlayWindow makeKeyAndVisible]hitTest:withEvent: 中返回 nil 并不总是有效。看来关键窗口需要正确实现 HitTest 方法?

我是否遗漏了一些关于事件转发的信息?

最佳答案

frontMostWindow 是否意味着 frontMostWin?

看起来即使我们只使用一个 UIWindow,hitTest:withEvent: 也会对其执行至少 2 次。所以,我想这是正常的。

您可以在

处收到 null
view = [frontMostWindow hitTest:p withEvent:event];

由于以下原因:

  • frontMostWindow 本身为空(例如,如果您只有一个窗口)
  • p 在 frontMostWindow 边界之外(例如,当 frontMostWindow 是键盘而您的触摸在其他地方时)
  • frontMostWindow 的属性 userInteractionEnabled 设置为 NO;

关于iphone - -[自定义窗口 HitTest :withEvent:] implementation to forward events,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11113223/

相关文章:

ios - 与导航 Controller 的协议(protocol)

ios - 如何在 nsobject 类的主线程中显示 uialertview

iphone - 如何实现iPhone的文件浏览设计

iphone - iPhone/iPad 和 iPhone(Retina)/iPad(Retina) 中图像的理想分辨率

iphone - 来自 UIImagePickerViewController 图像的方形缩略图

objective-c - 如何获得 NSViews 和 NSControls 的默认插入?

android - 如何在我们的应用程序中使用其他应用程序的应用程序功能

ios - 相当于只调用一次的 "viewDidLayoutSubviews"?

ios - 是否可以检测 facebook/gmail 横幅/警报通知

iphone - 调用 UIButton 也使用的方法?