Reputation: 1699
In my app I want to create a new UIWindow
over the main UIWindow, And I wrote as following, but it don't works.
first, i create a UIWindow
as the main window, and then make it key and visible, and then create a new UIWindow
overlay, but nothing happens.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
self.window.backgroundColor = [UIColor redColor];
ViewController *vc = [[ViewController alloc]initWithNibName:@"ViewController" bundle:nil];
self.window.rootViewController = vc;
[self.window makeKeyAndVisible];
UIWindow *window1 = [[UIWindow alloc] initWithFrame:CGRectMake(0, 0, 320, 320)];
window1.backgroundColor = [UIColor redColor];
window1.windowLevel = UIWindowLevelAlert;
[window1 makeKeyAndVisible];
return YES;
}
Upvotes: 46
Views: 86489
Reputation: 1844
SWIFT 5
In iOS13 and higher you must create UIWindow
with windowScene:
initializer as follows let overlayWindow = UIWindow(windowScene: YourScene)
. For lower iOS versions you should use frame:
initializer as follows let overlayWindow = UIWindow(frame: YourFrame)
.
After creating UIWindow
instance you can use code to display window as is written in @Nick Greg answer:
overlayWindow.windowLevel = UIWindow.Level.alert overlayWindow.rootViewController = UIViewController()//your controller or navController overlayWindow.makeKeyAndVisible()
Upvotes: 5
Reputation: 201
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.
Upvotes: 11
Reputation: 241
If you are using a window scene try this:
private var overlayWindow: UIWindow!
if let currentWindowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene {
overlayWindow = UIWindow(windowScene: currentWindowScene)
}
overlayWindow.windowLevel = UIWindow.Level.alert
overlayWindow.rootViewController = UIViewController()//your controller or navController
overlayWindow.makeKeyAndVisible()
Upvotes: 15
Reputation: 124
func createAdsWindow(){
let frame = CGRect.init(0, UIScreen.main.bounds.height - 60, UIScreen.main.bounds.width, 60)
adsWindow = UIWindow.init(frame: frame)
adsWindow!.backgroundColor = UIColor(colorBackground)
let adsViewController = UIViewController.init()
adsViewController.view.backgroundColor = UIColor.red
adsWindow?.rootViewController = adsViewController
adsWindow?.windowLevel = UIWindow.Level(rawValue: 2)
adsWindow?.makeKeyAndVisible()
}
Upvotes: 0
Reputation: 2583
if you just need to change shared window ViewController in swift 5
UIApplication.shared.keyWindow?.rootViewController = UINavigationController(rootViewController: yourViewController)
Upvotes: 1
Reputation: 31
Swift 4
To avoid memory leak, I prefer to initialise my custom window in this way, as proposed by Apple :
If you want to provide a custom window for your app, you must implement the getter method of this property and use it to create and return your custom window.
Example:
var myCustomWindow: UIWindow? = CustomWindow(frame: UIScreen.main.bounds)
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
let mainController: MainViewController = UIStoryboard(name: "Main", bundle: nil).instantiateInitialViewController() as! MainViewController
self.myCustomWindow?.rootViewController = mainController
self.myCustomWindow?.makeKeyAndVisible()
}
Upvotes: 3
Reputation: 1699
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!
Upvotes: 68
Reputation: 48552
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.
Upvotes: 13
Reputation: 131
In swift a new UIWindow
can be added as follows..
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
var viewController: ViewController?
var navigationController: UINavigationController?
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
self.window = UIWindow(frame: UIScreen.mainScreen().bounds)
self.viewController = ViewController(nibName: "ViewController", bundle:NSBundle.mainBundle())
self.navigationController = UINavigationController(rootViewController: self.viewController!)
self.window!.rootViewController = self.navigationController
// self.window!.addSubview(self.viewController!.view)
self.window!.makeKeyAndVisible()
return true
}
//Other methods..
}
Upvotes: -1
Reputation: 6342
try adding a UIView
on mainWindow not another UIWindow
like...
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
self.window.backgroundColor = [UIColor redColor];
ViewController *vc = [[ViewController alloc]initWithNibName:@"ViewController" bundle:nil];
self.window.rootViewController = vc;
[self.window makeKeyAndVisible];
UIView * viewAlert = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 320)];
viewAlert.backgroundColor = [UIColor redColor];
[self.window.rootViewController.view addSubView:viewAlert];
/* or you can use following..
[self.window addSubView:viewAlert];
*/
[viewAlert release]; //FOR NON ARC
return YES;
}
Upvotes: 0