30

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?

1
  • You can also try to get visible viewcontroller Commented May 31, 2019 at 18:44

8 Answers 8

57

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 } 
Sign up to request clarification or add additional context in comments.

3 Comments

Ok right, what a studip mistake! Btw, now there is a problem with RootViewController, how to access this view controller which is declared in storyboard? I guess making a new instance isn't a good idea? I mean RootViewController() leads to black screen, so should be another wait to access such controller
Here is how I do it in my code let storyboardId = "LoginStoryboardIdentifier" self.window?.rootViewController = self.window?.rootViewController?.storyboard?.instantiateViewControllerWithIdentifier(storyboardId) as? UIViewController
Works perfectly but while noticing memory consumption, I see no memory decrease when I replace the Root View controller (a) with (b). It means (a) has not wiped out from the memory, right? How to wipe it out from memory 1st and then show (b) controller
20

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 

1 Comment

Does this still work in Swift 5+, I can't seem to get this to work, the line appDelegate?.window throws an error saying cannot use optional chaining on non-optional value of type 'any', fixing it gives other errors.
11

Swift 3

This is a better way:

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

1 Comment

NSApplication is use in MacOS this question is tag in iOS
10

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 

2 Comments

This is how you access instance of UIWindow in Swift5 , iOS 13 & above versions to set it's rootViewController or to present any UIView. Thanks mate.
@Suhail I forgot 1 line to Add window.makeKeyAndVisible() Please check my Updated Answer it will sure work :)
5

You can also use conditional binding to reach the window.

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

Comments

2

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

Should be:

appDelegate.window!.rootViewController = RootViewController 

Comments

2

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 } } 

Comments

1

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

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

1 Comment

Whilst this code snippet is welcome, and may provide some help, it would be greatly improved if it included an explanation of how and why this solves the problem. Remember that you are answering the question for readers in the future, not just the person asking now! Please edit your answer to add explanation, and give an indication of what limitations and assumptions apply.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.