To create a new UIWindow over the main window
UIWindow *window1 = [[UIWindow alloc] initWithFrame:CGRectMake(0, 0, 320, 320)];window1.backgroundColor = [UIColor redColor];window1.windowLevel = UIWindowLevelAlert;[window1 makeKeyAndVisible];
Finally I know why it doesn't work, because window1 is a method var, and it will lost after the method executed. So I declare a new @property for it, as
@property (strong, nonatomic) UIWindow *window2;
and change the code like
UIWindow *window2 = [[UIWindow alloc] initWithFrame:CGRectMake(0, 80, 320, 320)];window2.backgroundColor = [UIColor redColor];window2.windowLevel = UIWindowLevelAlert;self.window2 = window2;[window2 makeKeyAndVisible];
it works!
Xcode 8 + Swift
class ViewController: UIViewController { var coveringWindow: UIWindow? func coverEverything() { coveringWindow = UIWindow(frame: (view.window?.frame)!) if let coveringWindow = coveringWindow { coveringWindow.windowLevel = UIWindowLevelAlert + 1 coveringWindow.isHidden = false } }}
According to the documentation, to receive events that do not have a relevant coordinate value, such as keyboard entry, make it key
instead of merely !
isHidden
:
coveringWindow.makeKeyAndVisible()
You can even control the transparency of its background, for a smoke effect:
coveringWindow.backgroundColor = UIColor(white: 0, alpha: 0.5)
Note that such window needs to handle orientation changes.
Your window1
object is a local variable, when the code runs out of this method, this object does not exist any more. Any UIWindow
object we created will be add to the [[UIApplication sharedApplication] windows]
, but this array only keeps a weak reference to any UIWindow
object, so it's up to your own code to keep the window object existing. Why apple implemented it like this, I guess, is [UIApplication sharedApplication]
object exists as long as the app runs, doing so to avoid keeping the UIWindow
objects which only needs to exist for a while living in the memory "forever".
What's more, your code could run with MRC.