10

I'm adding new UIWindow to show passcode view controller when the app is entering foreground.

Before iOS 13 in AppDelegate I had property var passcodeWindow = UIWindow(frame: UIScreen.main.bounds) where my rootViewController was the passcode view controller and in applicationWillEnterForeground method I was doing passcodeWindow.makeKeyAndVisible() to place it on the top.

Now when I want to implement the passcode functionality in iOS 13 there is a problem with this approach. I moved it to the sceneWillEnterForeground method in SceneDelegate, but it seems like I can't show passcodeWindow on top of the actual window in this scene.

I do it exactly the same as in AppDelegate and the passcodeWindow is not shown.

The way I do it in sceneWillEnterForeground in AppDelegate and in SceneDelegate:

passcodeWindow.rootViewController = passcodeViewController(type: .unlock)
passcodeWindow.makeKeyAndVisible()

I expect passcodeWindow to show on the top of current window in the scene.

Gleb A.
  • 1,180
  • 15
  • 24
Kamil Chmiel
  • 121
  • 1
  • 3
  • there are no warnings and visual debugger is not showing anything? – Lu_ Aug 02 '19 at 09:37
  • When I'm debugging after passcodeWindow.makeKeyAndVisible() I check the top viewController with UIApplication.shared.topViewController(). And it says that the top view controller is PasscodeViewController so it seems to be okay. In the console I get 8 times: "2019-08-02 11:44:08.466223+0200 MyProject[866:191801] [] nw_connection_receive_internal_block_invoke [C6] Receive reply failed with error "Operation canceled"" – Kamil Chmiel Aug 02 '19 at 09:49
  • Visual debugger shows only the main window, passcodeWindow is not even shown – Kamil Chmiel Aug 02 '19 at 09:55

3 Answers3

10

You can try this:

if #available(iOS 13.0, *) {
    if let currentWindowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene {
        passcodeWindow.windowScene = currentWindowScene
    }
}
RichardLiu
  • 115
  • 5
  • 3
    not working, I think it's because there are no strong reference to the local window instance, so that the window show up for a second and in the next run loop it get release due to ARC is 0. – andrew54068 Oct 09 '19 at 04:45
  • @rockhard https://stackoverflow.com/a/58167743/7332815 check this out – andrew54068 Jun 17 '20 at 17:42
  • This was the fix I was looking for on the iPhone. The link by @andrew54068 seems more geared towards showing a Modal, but I wanted a 'floating window' or Dialog of sorts. – dinesharjani Feb 10 '22 at 11:42
0

You need a strong reference for your UIWindow instance, and the most important thing is that you need to set "isHidden" property false.

newWindow = UIWindow.init(frame: CGRect.init(x: 0, y: 0, width: 100, height: 100))
newWindow?.backgroundColor = UIColor.systemBlue
newWindow?.windowScene = (scene as? UIWindowScene)
newWindow?.isHidden = false
Ryan
  • 1
  • 1
0

i was in a similar situation, where i needed to present a dialog on new window (above all)

as in most cases UIApplication.shared.connectedScenes.first would work fine, but i would go little bit extra mile to ensure that, like in my case i also have a CarPlay Scene

extension UIApplication {
    
    var keyWindowScene: UIWindowScene? {
        return self
            .connectedScenes
            .filter { $0.activationState == .foregroundActive }
            .compactMap { $0 as? UIWindowScene }
            .first
    }

}

and then

window.windowScene = UIApplication.shared.keyWindowScene
    
Peter Lapisu
  • 19,915
  • 16
  • 123
  • 179