4

デバイスの音量アップ/ダウンボタンを押したときに表示されるオーバーレイのようなオーバーレイを表示するカスタムウィンドウ (キーボードを含むすべての上にある必要があります) があります。

そこで、カスタム ウィンドウ 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. 私が[overlayWindow makeKeyAndVisible]戻ってきnilた場合、hitTest:withEvent:常に機能するとは限りません。キー ウィンドウには、ヒット テスト メソッドを適切に実装する必要があるように見えますか?

ここでイベント転送について何か不足していますか?

4

3 に答える 3

2

frontMostWindow は frontMostWin を意味しますか?

UIWindow を 1 つだけ使用hitTest:withEvent:しても、少なくとも 2 回は実行されるようです。ですから、それが普通だと思います。

でnullを受け取ることができます

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

次の理由により:

  • frontMostWindow 自体が null です (例として、ウィンドウが 1 つしかない場合)
  • p は frontMostWindow 境界の外にあります (たとえば、frontMostWindow がキーボードで、タッチが別の場所にある場合)
  • frontMostWindow にはプロパティ userInteractionEnabled が NO に設定されています。
于 2012-06-28T14:49:34.287 に答える
0

hitTest:withEvent: が数回呼び出されるのは正常です。これはおそらく、オーバーレイされたウィンドウに UILabel または UIImageView のみを表示し、タッチが自動的に回避されるためです。

ただし、別の OverlayWindow は実際には必要ないと思います。代わりに、keyWindow の上に UIView を配置することを検討してください。これにより、アプリケーションがよりクリーンになります...

于 2012-06-25T08:13:04.470 に答える