Take the 2-minute tour ×

I have a custom window (that should be on top of everything, including the keyboard) to show an overlay thing, something like the overlay you see when pressing the volume up/down buttons in the device.

So I made a custom window OverlayWindow so far everything works fine and windows in the back are receiving their events normally. However hitTest:withEvent: is called several times and sometimes it even returns nil. I wonder if that is normal/correct? If not how can I fix that?

// 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)


    // 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;


Also I've noticed that

  1. if hitTest:withEvent: always returns nil it works too. This is only when I call overlayWindow.hidden = NO;

  2. if I call [overlayWindow makeKeyAndVisible] returning nil in hitTest:withEvent: does not always work. It looks like a key window requires a proper implementation of the hit testing method?

Am I missing something about event forwarding here?

share|improve this question
add comment

2 Answers

up vote 2 down vote accepted

Do frontMostWindow means frontMostWin?

It looks like even if we use only one UIWindow, hitTest:withEvent: will be executed on it at least 2 times. So, I guess it is normal.

You can receive null at

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

due to following reasons:

  • frontMostWindow is null itself (as example, if you have only one window)
  • p is ouside frontMostWindow bounds (as example, when frontMostWindow is keyboard and your touch is somewhere else)
  • frontMostWindow have property userInteractionEnabled set to NO;
share|improve this answer
add comment

hitTest:withEvent: being call several times is normal. This is probably because you only display a UILabel or UIImageView on the overlayed window and thus touches are automatically forwareded.

However I think you don't really need another OverlayWindow, instead you might consider a UIView on the top of the keyWindow. This should make your application cleaner...

share|improve this answer
do you know what causes hitTest:withEvent: called several times? does it affect the performance? –  nacho4d Jun 25 '12 at 14:09
add comment

Your Answer


