Reputation:
I'm trying to present the top view controller as the root view controller, the whole code works except that line :
var topController: UIViewController = UIApplication.shared.keyWindow!.rootViewController!
I get the warning :
'keyWindow' was deprecated in iOS 13.0: Should not be used for applications that support multiple scenes as it returns a key window across all connected scenes
Then when I say :
var topController: UIViewController = UIApplication.shared.windows.first { $0.isKeyWindow }!.rootViewController!
I get :
'windows' was deprecated in iOS 15.0: Use UIWindowScene.windows on a relevant window scene instead
And then when I say:
var topController: UIViewController = UIWindowScene.windows.first { $0.isKeyWindow }!.rootViewController!
I get :
Instance member 'windows' cannot be used on type 'UIWindowScene'; did you mean to use a value of this type instead?
Can somebody help me? Sorry if this sounds easy but I'm still a novice. Thanks
Upvotes: 2
Views: 6268
Reputation: 4711
I make and use some extensions of UIApplication.
func findWindowScenes() -> [UIWindowScene] {
return Self.shared.connectedScenes.compactMap({ $0 as? UIWindowScene })
}
func findKeyWindow() -> UIWindow? {
if #available(iOS 15, *) {
let scenes = findWindowScenes()
return scenes.first(where: { $0.keyWindow != nil })?.keyWindow ?? scenes.first?.keyWindow
} else {
return Self.shared.windows.filter({ $0.isKeyWindow }).first
}
}
func findKeyRootViewController() -> UIViewController? {
return findKeyWindow()?.rootViewController
}
Upvotes: 0
Reputation: 2315
You can use the following code base
let window = UIApplication.shared.windows.first(where: { $0.isKeyWindow })
extension UIApplication {
class var topViewController: UIViewController? { return getTopViewController() }
private class func getTopViewController(
base: UIViewController? = UIApplication.keyWindow?.rootViewController) -> UIViewController? {
if let nav = base as? UINavigationController { return getTopViewController(base: nav.visibleViewController) }
if let tab = base as? UITabBarController {
if let selected = tab.selectedViewController { return getTopViewController(base: selected) }
}
if let presented = base?.presentedViewController { return getTopViewController(base: presented) }
return base
}
}
extension UIApplication {
static var keyWindow: UIWindow? {
return shared.windows.first(where: {$0.isKeyWindow})
}
}
Upvotes: -2
Reputation: 1193
you can set/get root view controller as follow:
// getting the all scenes
let scenes = UIApplication.shared.connectedScenes
// getting windowScene from scenes
let windowScene = scenes.first as? UIWindowScene
// getting window from windowScene
let window = windowScene?.windows.first
// getting the root view controller
let rootVC = window?.rootViewController
// changing the root view controller
window?.rootViewController = someVc
Upvotes: 4