I have been playing around with using multiple UIWindows in an iOS application at my current client for the last few days and thought I would share what I perceive to be the pro’s and con’s. I will cover the technical challenges / observations I have witnessed when using UIWindows that sit above UIAlertViews when accessibility / VoiceOver mode is on in another post otherwise it will get lost.
Why would I want to use multiple UIWindows?
Well I guess a couple of the reasons would be that maybe you want to display a view that shows above system UIAlertViews, can cover the default keyboard or even make your app look like it is modifying the statusbar like Reeder.
Another great reason could be that you want to cover everything on your iOS application before it is placed into the background so that no screenshot can be taken of sensitive data, if you have any of course.
Getting started with using multiple UIWindows
UIWindows are simply special UIViews that can have their display order controlled via the windowLevel property. You dont need to add a UIWindow as a subview of any other view. By simply creating a new UIWindow and calling either [window setHidden:NO] or [window makeKeyAndVisible] depending on the level you gave it it will most likely appear on your screen.
All iOS apps start off with a UIWindow that you normally know as the [UIApplication sharedApplication].keyWindow or [UIApplication sharedApplication].delegate.window, this is the window where you normally set a window.rootViewController and from that point on you normally just deal with UIViewControllers.
There are 3 default window enum levels defined which are:
If you wanted to create a window that displayed above the statusbar but underneath UIAlertViews you could create a window with a windowLevel of UIWindowLevelStatusBar. If you wanted to create a window that sat above everything in your app you could simply set it to something like window.windowLevel = UIWindowLevelAlert + 1 would be fine.
Benefits I have found with using multiple UIWindows
- It is super simple to display a view above everything else on your screen.
- You can create your own custom UIAlertViews or Progress Overlays that can sit above everything else.
- Allows you to hide sensitive data quickly when your app is moving to the background. Before you app moves to the background simply put up a UIWindow that covers the whole screen, this will stop iOS from taking a screenshot and saving it on your device … of course this is only a concern for the extremely paranoid.
Some issues / gotchas you might run into when using your own UIWindows
- You have to handle any rotation events manually. Your custom UIWindows will not get any rotation notifications you must subscribe to these yourself and layout your window for the given orientation manually.
- If another window in your application has a higher window level than your and your not in a position to change it well there is nothing you can do, your window will simply not appear above it.
- UIAlertViews and UIActionSheets are displayed on the level of UIWindowLevelAlert, if you need to cover them up keep this in mind.
- UIPopovers seem to appear on the UIWindowLevelStatusBar, alerts still appear over UIPopovers so this makes sense.
- UIAlertViews have their own special window which can be a pain in the arse which I will go into more detail in a follow up post.
- When you make a UIWindow the keyWindow it means it will become the first responder for the ios keyboard etc.