Andrejs Mironovs
Andrejs Mironovs

Reputation: 43

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

Upvotes: 0

Views: 925

Answers (4)

Vivek
Vivek

Reputation: 5213

Simple solution for your case

  1. 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()
     // Now you can change status bar style default or other style
     UIApplication.shared.statusBarStyle = .default
    
  2. New UIWindow dismissal:

     UIView.animate(
         withDuration: 1.0,
         delay: 0,
         usingSpringWithDamping: 1,
         initialSpringVelocity: 0,
         options: .curveEaseOut,
         animations: { [weak self] in
             self?.newWindow?.alpha = 0
             // Revert back to default
             UIApplication.shared.statusBarStyle = .lightContent
         },
         completion: { [weak self] _ in
             self?.newWindow?.windowLevel = 0
             self?.newWindow?.rootViewController = nil
             self?.newWindow?.alpha = 1
             self?.mainWindow.makeKeyAndVisible()
         }
     )
    

Upvotes: 0

Andrejs Mironovs
Andrejs Mironovs

Reputation: 43

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!

Upvotes: 1

Hemant Solanki
Hemant Solanki

Reputation: 64

  1. Please add the following code on your first controller in which you change status bar color Light.

    override func viewDidAppear(_ animated: Bool) { UIApplication.shared.setStatusBarStyle(UIStatusBarStyle.lightContent, animated: false) }

  2. Now in second Controller in which you want default status bar style, put the code :

    override func viewDidAppear(_ animated: Bool) { UIApplication.shared.setStatusBarStyle(UIStatusBarStyle.default, animated: false) }

You will definitely get the proper solution by above code

Upvotes: 0

Ragul
Ragul

Reputation: 3196

change the statusbar style on ViewWillAppear

override func viewWillAppear(_ animated: Bool) {
    UIApplication.shared.statusBarStyle = .lightContent
}

Upvotes: 0

Related Questions