37

I thought it was easy as [myWindow resignKeyWindow] and [self.window makeKeyAndVisible] but I guess not… Would you guys know what to do?

Thanks :)

G33kz0r
  • 750
  • 1
  • 8
  • 17

7 Answers7

97

The correct way to hide a window is to set the hidden property to YES. To remove it from UIApplication's windows property you just release the window (in ARC you set all references to nil).

Of course you would want to have another window in place at this time.

Nikolai Ruhe
  • 81,520
  • 17
  • 180
  • 200
  • 4
    can't work now , ios 12 , seems like can't remove it from UIApplication's windows after it makeKeyWindow. – Sven Tan Jan 31 '19 at 11:05
  • 4
    It is not removing keywindow anymore and the list keeps growing. Any other ideas? – adev Feb 21 '19 at 05:21
  • 1
    any feedback @adev ? – JERC Apr 11 '19 at 18:49
  • @JERC, nope. I couldn't find any solution. I am just hiding it for now and it is not released from that list too. – adev Apr 12 '19 at 23:10
  • 1
    Having a strong reference to the window and then setting reference to nil when done is enough in iOS 13 to switch control back to the initial window. – C6Silver Nov 29 '19 at 21:26
  • It unfortunately still stays in the application's `windows` property – Zoltán Apr 06 '21 at 12:18
  • For me, the window does not *immediately* leave the `windows` property, but after a short interval it is indeed removed. But you do need to call `makeKeyAndVisible()` on another window. – Dave Goldman Sep 01 '21 at 17:21
16

Do not invoke -resignKeyWindow directly, it was meant to be overridden to execute some code when your UIWindows gets removed. In order to remove old window you need to create new instance of UIWindow and make it -makeKeyAndVisible, the old window will resign its key status. In iOS 4 it will even garbage collect your old UIWindow, provided you don't have any references to it. Doing this in iOS 3.x would have disastrous effects. Warned ya.

bioffe
  • 6,283
  • 3
  • 50
  • 65
15

Here is how you can remove UIWindow on iOS 13 in a backward-compatible way. Tested on iOS 12, iOS 13, iPadOS with multi-window support:

extension UIWindow {
    func dismiss() {
        isHidden = true

        if #available(iOS 13, *) {
            windowScene = nil
        }
    }
}

Usage:

// Detect key window
let keyWindow = UIApplication.shared.windows.first { $0.isKeyWindow }

// Dismiss key window (if any)
keyWindow?.dismiss()
Vadim Bulavin
  • 3,697
  • 25
  • 19
  • yep, it works, set window's windowScene to nil will removed from application's windows. Thanks. – Meilbn Mar 11 '23 at 01:26
4

This extension helped me in some more cases:

/// Removes window from windows stack
func remove() {
    rootViewController?.view.removeFromSuperview()
    rootViewController = nil
    isHidden = true
    
    // https://stackoverflow.com/a/59988501/4124265
    if #available(iOS 13.0, *) {
        windowScene = nil
    }
}
Anton Plebanovich
  • 1,296
  • 17
  • 17
0

You cannot remove the window from the app delegate. However you can remove any custom windows created.

To remove the window you must first provide a replacement. So we get the default window.

AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];

We now have access to the default window via the app delegate's window property.

Now get the original or custom navigation controller. Assign self to rootViewController.

Calling makeKeyandVisible removes any windows and assigns the app delegate's window as the key window. Set rootViewController to the navigation controller you just created and you are good to go!

DEMONavigationController *demoNav = [[DEMONavigationController alloc]initWithRootViewController:self];
[appDelegate.window makeKeyAndVisible];
appDelegate.window.rootViewController = demoNav;
shim
  • 9,289
  • 12
  • 69
  • 108
0

If you have any window other than app window, use it ..

let mainWindow = UIApplication.shared.delegate?.window
mainWindow??.makeKeyAndVisible()
Avinash
  • 4,304
  • 1
  • 23
  • 18
-9

I have the same issue, it may helps.

You needs to destroy all strong ref before remove and dealloc a windows, especially the rootWindowController. I think below code is enough to delete any window:

[self.window.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)];
self.window.rootViewController = nil;
[self.window resignKeyWindow];
[self.window removeFromSuperview];
shim
  • 9,289
  • 12
  • 69
  • 108
flypig
  • 1,260
  • 1
  • 18
  • 23