iosswiftuiwindow

Restore status bar state after closing second UIWindow


There is main UIWindow that holds MainViewController which uses lightContent as preferredStatusBarStyle. I've created second UIWindow instance to show PopupViewController, which uses default as preferredStatusBarStyle.

When I show second UIWindow with PopupViewController status bar style changes to default, but when I hide it style does not changes back to lightContent.

The same problem applies to situation when I have VC with hidden status bar in popup window - status bar does not shows when popup window is dismissed.

New UIWindow creation:

// Prepare window to show dialog box in
newWindow = UIWindow(frame: UIScreen.main.bounds)
newWindow?.windowLevel = 3

// Overlay new window
newWindow?.makeKeyAndVisible()
self.mainWindow.windowLevel = 1
self.mainWindow.endEditing(true)
newWindow?.isHidden = false

// Display dialog
newWindow?.rootViewController = PopupViewController()

New UIWindow dismissal:

UIView.animate(
    withDuration: 1.0,
    delay: 0,
    usingSpringWithDamping: 1,
    initialSpringVelocity: 0,
    options: .curveEaseOut,
    animations: { [weak self] in
        self?.newWindow?.alpha = 0
    },
    completion: { [weak self] _ in
        self?.newWindow?.windowLevel = 0
        self?.newWindow?.rootViewController = nil
        self?.newWindow?.alpha = 1
        self?.mainWindow.makeKeyAndVisible()
    }
)

Thank you!

EDIT: Popup can appear at any time, I don't know which VC was active at that moment


Solution

  • The thing I was looking for was UIViewController.setNeedsStatusBarAppearanceUpdate(). It is convenient method to tell VC that status bar appearance was changed and needs to be restored.

    // make main window key but transparent
    self.mainWindow.alpha = 0
    self.newWindow?.windowLevel = 0
    self.newWindow?.alpha = 1
    self.mainWindow.makeKey()
    
    // restore status bar appearance  
    self.mainWindow.rootViewController!.setNeedsStatusBarAppearanceUpdate()
    
    // Fade in main window with (status bar is in proper state at this moment)
    UIView.animate(
            withDuration: 0.9,
            delay: 0,
            usingSpringWithDamping: 1,
            initialSpringVelocity: 0,
            options: .curveEaseIn,
            animations: { [weak self] in
                self?.mainWindow.alpha = 1
            },
            completion: { [weak self] _ in
                // destroy popup VC
                self?.newWindow?.rootViewController = nil
            }
    )
    

    Here is useful article on this subject

    Thanks everyone!