multiple windows arrangement by setting window.windowLevel works on iOS 13 but not on iOS 12

962 Views Asked by At

In our application, we present 3 viewControllers on 3 different UIWindows.

We had issue with arrangement of these modals. I tried to fix the issue by adjusting the window.windowLevel property for each UIWindow.

For some unknown reason, the fix works on iOS 13.1.2 but not on iOS 12.1.1. Any idea? Thanks.

1

There are 1 best solutions below

0
On

I believe windowLevel is not a property you are looking for at all. Even if this works or should work it is incidental as this property describes window presentation style more that order of windows.

You could keep removing/adding windows or even making them hidden as part of normal API. Or you could just use makeKeyAndVisible on the window you want to see on top.

See the following quick example of usage:

class ViewController: UIViewController {

    private static var windows: [UIWindow] = {
        let colors: [UIColor] = [.red, .blue, .green]
        return colors.map { color in


            let window: UIWindow
            if #available(iOS 13.0, *) {
                let scene = UIApplication.shared.windows.first!.windowScene!
                window = UIWindow(windowScene: scene)
            } else {
                // Fallback on earlier versions
                window = UIWindow(frame: UIScreen.main.bounds)
            }

            window.rootViewController = {
                let controller = ViewController()
                controller.view.backgroundColor = color
                return controller
            }()
            window.makeKeyAndVisible()
            return window
        }
    }()
    private static var windowIndex: Int = 0

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
        view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(onTap)))
    }

    @objc private func onTap() {
        let actualIndex = ViewController.windowIndex%ViewController.windows.count
        ViewController.windows[actualIndex].makeKeyAndVisible()
        ViewController.windowIndex += 1
    }

}

Lazily 3 windows are loaded each having a view controller with it's own distinct color. When you tap the screen a "next" window should appear on top so you can keep toggling between the windows.

An even safer implementation could be as easy as the following:

@objc private func onTap() {
    let actualIndex = ViewController.windowIndex%ViewController.windows.count
    ViewController.windows.enumerated().forEach { index, window in
        if index == actualIndex {
            window.makeKeyAndVisible()
        } else {
            window.isHidden = true
        }
    }
    ViewController.windowIndex += 1
}