theDC
theDC

Reputation: 6484

Accessing AppDelegate window from viewController

I make walkthrough (onboarding flow) in my app and I'd like to have a skip button. The button is located on viewController, so I figured out that the best way to move to another viewController would be access app delegate window.

However, it keeps getting me an error that AppDelegate.Type does not have a member called "window".

@IBAction func skipWalkthrough(sender: AnyObject) {
    let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
    AppDelegate.window!.rootViewController = RootViewController   
}

Is there anything wrong with such approach?

Upvotes: 31

Views: 54523

Answers (8)

Nikunj Kumbhani
Nikunj Kumbhani

Reputation: 3924

appDelegate.window!.rootViewController is not working in Swift 5

Here is working code

Add below extension

extension UIWindow {
    static var key: UIWindow! {
        if #available(iOS 13, *) {
            return UIApplication.shared.windows.first { $0.isKeyWindow }
        } else {
            return UIApplication.shared.keyWindow
        }
    }
}

use

let mainSB = UIStoryboard(name: "Main", bundle: nil)
                    
if let RootVc = mainSB.instantiateViewController(withIdentifier: "NavigationController") as? UINavigationController{
    UIWindow.key.rootViewController = RootVc
}

UIWindow.key // to access only window

Upvotes: 10

Humza Shahid
Humza Shahid

Reputation: 33

This solution work for : After Login / Register Programmatically add UITabbarController

let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
appDelegate.window!.rootViewController = tabs
appDelegate.window!.makeKeyAndVisible()

Upvotes: 1

Dasoga
Dasoga

Reputation: 5695

This is for with or without Storyboard and it is working for Swift 3+

let appDelegate = UIApplication.shared.delegate as? AppDelegate
let mainStoryboard = UIStoryboard(name: "Main", bundle: nil)
let homeController = mainStoryboard.instantiateViewController(withIdentifier: "HomeViewController") as! HomeViewController
appDelegate?.window?.rootViewController = homeController

Upvotes: 20

Gustavo Vollbrecht
Gustavo Vollbrecht

Reputation: 3256

You can also use conditional binding to reach the window.

if let window = UIApplication.shared.windows.first {
    // use window here.
}

Upvotes: 5

Umit Kaya
Umit Kaya

Reputation: 5961

You can access tab bar anywhere from the app. Use below:

let appDelegate = UIApplication.shared.delegate as! AppDelegate

if let tabBarController = appDelegate.window!.rootViewController as? UITabBarController {
    if let tabItems = tabBarController.tabBar.items {
       let tabItem = tabItems[2]
       tabItem.badgeValue = "5" //enter any value
    }
}

Upvotes: 2

Stefan Salatic
Stefan Salatic

Reputation: 4523

You have a typo it is supposed to be appDelegate not AppDelegate. So like this:

@IBAction func skipWalkthrough(sender: AnyObject) {
    let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
    appDelegate.window!.rootViewController = RootViewController   
}

Swift 3.2

@IBAction func skipWalkthrough(_ sender: AnyObject) {
        let appDelegate = UIApplication.shared.delegate as! AppDelegate
        appDelegate.window!.rootViewController = controller
    }

Upvotes: 57

Ted Lowery
Ted Lowery

Reputation: 1545

Swift 3

This is a better way:

    if let window = NSApplication.shared().windows.first {
        window.acceptsMouseMovedEvents = true;
    }

Upvotes: 11

giorashc
giorashc

Reputation: 13713

You are using the protocol name (i.e. AppDelegate) instead of the instance:

Should be:

appDelegate.window!.rootViewController = RootViewController   

Upvotes: 2

Related Questions