Search code examples
iosiphoneios7overlayuiwindow

iOS: Issues with creating another UIWindow as an overlay (iOS 7 issues?)


I want to create an overlay view above all other views (including the keyboard), and creating another UIWindow seems to be the way to do this. After reading through the Windows section of the View Programming Guide and some other documents online, it seems like I just need to...

  • create the window with the screen bounds,
  • set its windowLevel to UIWindowLevelStatusBar,
  • set userInteractionEnabled to NO (so it would ignore touches),
  • and make it visible by setting its hidden property to NO (without making it the key window, so it does not receive non-touch events).

Here's the code in my app delegate:

self.overlayWindow = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
self.overlayWindow.backgroundColor = [UIColor clearColor];
self.overlayWindow.windowLevel = UIWindowLevelStatusBar;
self.overlayWindow.userInteractionEnabled = NO;
self.overlayWindow.rootViewController = [[OverlayViewController alloc] initWithNibName:nil bundle:nil];
self.overlayWindow.hidden = NO;

However, I ran into a few issues:

  1. [self.overlayWindow.rootViewController preferredStatusBarStyle] is setting the status bar text color when I actually want the root view controller of my original window to be doing this.
  2. A big issue is that the extra window is somehow messing up my handling of the software keyboard notifications. It seems like I still get the notifications, but my app is responding strangely in some instances. (I won't explain what these strange behaviors are because they are beside the point.) The point is that I shouldn't be getting these strange behaviors at all: I'm just trying to paint an overlay over the app, and the app should behave just as it did before.
  3. I would like the rotations from overlayWindow to match up to those of my original window, but it is rotating independently. For example, the swipe-to-go-back gesture of UINavigationController locks the interface orientation, but overlayWindow is still able to rotate during this.

What should I do to fix this, so I just get a harmless overlay over the app?


Solution

  • I've accomplished something very similar with using a window. In my case I didn't use a UIViewController attached to the window, just the needed subviews so it looked correct. In order to handle the rotation correctly you can listen to the NSNotification

    UIApplicationDidChangeStatusBarOrientationNotification
    

    In the method handler you can grab the device orientation as with a call like so

    UIInterfaceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation];
    

    And then you can use CGAffineTransformMakeRotation to rotate the views inside your window to the correct orientation. From the looks of the method you would think you would get the notification after the device orientation has animated, however you'll get it before and when you rotate your view with a transform your rotation will be animated along with everything else (this is assuming things are centered, if there not things are more complicated). SVProgress hud would be an good example to study if you wanted an example https://github.com/samvermette/SVProgressHUD