Uiwindow Not Showing Over Content in iOS 13

UIWindow not showing over content in iOS 13

I was experiencing the same problems while upgrading my code for iOS 13 scenes pattern. With parts of your second code snippet I managed to fix everything so my windows are appearing again. I was doing the same as you except for the last line. Try removing viewController.present(...). Here's my code:

let windowScene = UIApplication.shared
.connectedScenes
.filter { $0.activationState == .foregroundActive }
.first
if let windowScene = windowScene as? UIWindowScene {
popupWindow = UIWindow(windowScene: windowScene)
}

Then I present it like you do:

popupWindow?.frame = UIScreen.main.bounds
popupWindow?.backgroundColor = .clear
popupWindow?.windowLevel = UIWindow.Level.statusBar + 1
popupWindow?.rootViewController = self as? UIViewController
popupWindow?.makeKeyAndVisible()

Anyway, I personally think that the problem is in viewController.present(...), because you show a window with that controller and immediately present some 'self', so it depends on what 'self' really is.

Also worth mentioning that I store a reference to the window you're moving from inside my controller. If this is still useless for you I can only show my small repo that uses this code. Have a look inside AnyPopupController.swift and Popup.swift files.

Hope that helps, @SirOz

How do I add a view to the top of an app in iOS 13/14

You have to create a second UIWindow, assign the rootViewController and make it visible.

The code bellow is for SwiftUI, but you can do the same with UIKit, just create a window and set window.isHidden = false.

let secondWindow = UIWindow(windowScene: windowScene)
secondWindow.frame = CGRect(x: 0, y: 40, width: UIScreen.main.bounds.size.width, height: 100)
let someView = Text("I am on top of everything")
secondWindow.rootViewController = UIHostingController(rootView: someView)
secondWindow.isHidden = false

Depending on how many windows you have. You might need to change the windowLevel of your second window.
You can check if the window is displayed using Debug View Hierarchy from Xcode.

This is a UIKit example without SceneDelegate. If you have scene delegate you have to pass the window scene to the UIWindow init.
Don't forget to retain the second window.


@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
private enum Constants {
static let sessionConfiguration = URLSessionConfiguration.default
}

var window: UIWindow?
var secondWindow: UIWindow?

// MARK: - UIApplicationDelegate

func application(_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil) -> Bool {

let window = UIWindow(frame: UIScreen.main.bounds)
self.window = window
let viewController = UIViewController()
viewController.view.backgroundColor = .red

window.rootViewController = viewController
window.makeKeyAndVisible()

let secondWindow = UIWindow()
secondWindow.frame = CGRect(
x: 0,
y: 40,
width: UIScreen.main.bounds.size.width,
height: 100
)

let secondController = UIViewController()
secondController.view.backgroundColor = .blue
secondWindow.rootViewController = secondController
secondWindow.isHidden = false
self.secondWindow = secondWindow

return true
}
}

Sample Image

How to resolve: 'keyWindow' was deprecated in iOS 13.0

This is my solution:

let keyWindow = UIApplication.shared.connectedScenes
.filter({$0.activationState == .foregroundActive})
.compactMap({$0 as? UIWindowScene})
.first?.windows
.filter({$0.isKeyWindow}).first

Usage e.g.:

keyWindow?.endEditing(true)


Related Topics



Leave a reply



Submit