I need to programatically set initial view controller (based on user login status).
This is my initial code:
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let mainRootController = storyboard.instantiateViewControllerWithIdentifier("MainViewController") as UIViewController
if self.window != nil {
let navigationController:UINavigationController = storyboard.instantiateInitialViewController() as UINavigationController
navigationController.viewControllers = [mainRootController]
self.window!.rootViewController = navigationController
}
return true
This loads 'MainViewController' fine. But I am missing UITabBarController also and I don't know how to set it up programatically here.
Any help?
Try this one:
let tabBar = UITabBarController()
tabBar.viewControllers = [navigationController]
self.window!.rootViewController
Related
hi I followed some tutorial in stack for only seeing UIPageviewcontroller running at first time I find the best one and than implement it in app delegate .... first of all I have only one storyboard with two viewcontroller which first one is my PageViewController and second one is my Loginvc
I implemented this code on appdelegate and I get crash everything looks good but I get crash this is the code that I have implement it
var window: UIWindow?
var story : UIStoryboard?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
UIApplication.shared.statusBarStyle = .lightContent
window = UIWindow(frame: UIScreen.main.bounds)
window?.makeKeyAndVisible()
let lunchedBefore = UserDefaults.standard.bool(forKey: "lunchedBefore")
if lunchedBefore {
story = UIStoryboard(name: "TShopUI", bundle: nil)
let rootcontroller = story?.instantiateViewController(withIdentifier: "LoginVC")
if let window = self.window {
window.rootViewController = rootcontroller
}
} else {
UserDefaults.standard.set(true, forKey: "lunchedBefore")
story = UIStoryboard(name: "TShopUI", bundle: nil)
let rootcontroller = story?.instantiateViewController(withIdentifier: "MainVC")
if let window = self.window {
window.rootViewController = rootcontroller
}
}
return true
}
thanks for every help
please answer as clear as you can I'm new to iOS development
It's crashing because of UserDefaults, you have to handle UserDefaults like below,
Updated: instead of Bool we can use object. So Whether the if condition satisfies, it's not a first launch. else it's first launch.
var window: UIWindow?
var story : UIStoryboard?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
UIApplication.shared.statusBarStyle = .lightContent
window = UIWindow(frame: UIScreen.main.bounds)
window?.makeKeyAndVisible()
if let lunchedBefore = UserDefaults.standard.object(forKey: "lunchedBefore") {
story = UIStoryboard(name: "TShopUI", bundle: nil)
let rootcontroller = story?.instantiateViewController(withIdentifier: "LoginVC")
if let window = self.window {
window.rootViewController = rootcontroller
}
} else {
UserDefaults.standard.set(true, forKey: "lunchedBefore")
story = UIStoryboard(name: "TShopUI", bundle: nil)
let rootcontroller = story?.instantiateViewController(withIdentifier: "MainVC")
if let window = self.window {
window.rootViewController = rootcontroller
}
}
return true
}
the problem was that I should set a storyboard ID for each view controller and than in delegate set their identifier
I want to access a UIViewcontroller in AppDelegate. The hierarchy is shown here:
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
let navController = self.window!.rootViewController as! UINavigationController
let tabController = navController.topViewController as! UITabBarController
var postController = tabController.topViewController as! UITableViewController
// It is incorrect. has no member of topViewController
return true
}
Have you tried something like:
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
let navController = self.window!.rootViewController as! UINavigationController
let tabController = navController.topViewController as! UITabBarController
var postController = tabController.viewControllers[0]
// It is incorrect. has no member of topViewController
return true
}
Tab bar controller manages a list of ViewControllers. In this case you want the first one in the list. Note the syntax might be a bit wrong as I don't have much swift experience!
var postController = tabController.viewControllers[0]
That is the part I cahanged.
if var topController = UIApplication.sharedApplication().keyWindow?.rootViewController {
while let presentedViewController = topController.presentedViewController {
topController = presentedViewController
}
// topController should now be your topmost view controller
}
The problem is that you shouldn't have to access you controller from AppDelegate, it's a mistake in your app's architecture.
AppDelegate should only be used for app's lifecycle (launch/activation/deactivation/push notifications/...)
Why would you like to access your viewController here ?
you already did your forwarding with the storyboard,
all you have to do is:
func applicationDidFinishLaunching(_ application: UIApplication) {
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let navigationController = storyboard.instantiateViewController(withIdentifier: "navigationController") // here you should insert your identifier (storyboard -> navigationcontroller -> Identity -> Storyboard ID)
window!.rootViewController = navigationController
window!.makeKeyAndVisible()
}
You can use storyboard identifier to access the view controller
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let viewController = storyboard.instantiateViewController(withIdentifier: "storyboardIdentifier")
When I launching my application, I want go to the custom view controller, but the default first controller in storyboard:
I want go to brown vc when launch my app:
My method is below, but get a black screen with Unable to capture view hierarchy
1) In Info.plist, delete the Main storyboard file base name line.
2) In my Appdelegate.swift:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
let sb:UIStoryboard = UIStoryboard.init(name: "Main", bundle: nil)
let nav: CustomNavController = sb.instantiateViewController(withIdentifier: "CustomNavController") as! CustomNavController
let red_vc:ViewController = sb.instantiateViewController(withIdentifier: "ViewController") as! ViewController
let green_vc:ViewController2 = sb.instantiateViewController(withIdentifier: "ViewController2") as! ViewController2
let brown_vc:ViewController3 = sb.instantiateViewController(withIdentifier: "ViewController3") as! ViewController3
nav.viewControllers = [red_vc, green_vc, brown_vc]
self.window? = UIWindow.init(frame: UIScreen.main.bounds)
self.window?.rootViewController = nav
self.window?.makeKeyAndVisible()
return true
}
Result get a black screen:
Is which step I mistake? and how can I get it well ? When launch my application I want go to brown vc.
ATTEMPT - 1
Using push to brown vc, it is not work too:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
let sb:UIStoryboard = UIStoryboard.init(name: "Main", bundle: nil)
let nav: CustomNavController = sb.instantiateViewController(withIdentifier: "CustomNavController") as! CustomNavController
let red_vc:ViewController = sb.instantiateViewController(withIdentifier: "ViewController") as! ViewController
let green_vc:ViewController2 = sb.instantiateViewController(withIdentifier: "ViewController2") as! ViewController2
let brown_vc:ViewController3 = sb.instantiateViewController(withIdentifier: "ViewController3") as! ViewController3
//nav.viewControllers = [red_vc, green_vc, brown_vc]
nav.pushViewController(red_vc, animated: false)
nav.pushViewController(green_vc, animated: false)
nav.pushViewController(brown_vc, animated: false)
self.window? = UIWindow.init(frame: UIScreen.main.bounds)
self.window?.rootViewController = nav
self.window?.makeKeyAndVisible()
return true
}
You no need delete Main storyboard file base name in Info.plist
In AppDelegate:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
let mainStoryboard = UIStoryboard.init(name: "Main", bundle: nil)
let brownVC = mainStoryboard.instantiateViewController(withIdentifier: "brownVCIdentifier") as! BrownViewController
let navigationController = application.windows[0].rootViewController as! UINavigationController
navigationController.isNavigationBarHidden = true
navigationController.pushViewController(brownVC, animated: false)
return true
}
(or)
In RedViewController(first viewController):
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
let brownVC = storyboard?.instantiateViewController(withIdentifier: "brownVCIdentifier") as! BrownViewController
navigationController?.isNavigationBarHidden = true
navigationController?.pushViewController(brownVC, animated: false)
}
Github link:
https://github.com/k-sathireddy/DirectNavigationSample
You are setting the root viewcontroller as nav which has no UIView and it's creating a blank view due to which you see the black view when app is launched.
this code nav.viewControllers = [red_vc, green_vc, brown_vc] is not making any sense as you cannot set view controllers like this for UINavigationController. Navigation controller works with PUSH/POP mechanism hence you need to push the view controllers on nav controller which will correctly setup the view hierarchy. Push the controllers to brown_vc in nav and it should work.
I am learning to develop iOS and come across to this awesome library SlideMenuController. I am able to make use of this library to create awesome slide menu easily.
However, there are some problem that I am facing during implementing with this library.
Environment
In my project storyboard, I have 1 TabBarViewController and 2 ViewController which is under this TabBarViewController. I also have 2 independent ViewController which are LoginViewController and LeftMenuViewController.
I have below code in my AppDelegate.swift file
...
var window: UIWindow?
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let mainViewController = storyboard.instantiateViewControllerWithIdentifier("TabBarViewController") as! TabBarViewController
let leftViewController = storyboard.instantiateViewControllerWithIdentifier("LeftMenuViewController") as! LeftMenuViewController
let slideMenuController = SlideMenuController(mainViewController: mainViewController, leftMenuViewController: leftViewController)
SlideMenuOptions.contentViewScale = 1
SlideMenuOptions.hideStatusBar = false;
self.window?.rootViewController = slideMenuController
self.window?.makeKeyAndVisible()
return true
}
...
Everything work perfectly if I don't need my login view as a initial view. I notice that this line of code self.window?.rootViewController = slideMenuController will always make sure that view in mainViewController to be the initial view when the app open.
How can I have my LoginView as the initial view when my app start up and the slide menu is still bind to the TabBarViewController and working properly?
I have try to move the code from AppDelegate.swift to viewDidLoad() function in TabBarViewController.swift but no luck. It is not working.
Need some guilds and help on this. Thanks.
you can use this code instead of yours :
var window: UIWindow?
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let mainViewController = storyboard.instantiateViewControllerWithIdentifier("TabBarViewController") as! TabBarViewController
let leftViewController = storyboard.instantiateViewControllerWithIdentifier("LeftMenuViewController") as! LeftMenuViewController
let loginViewController = storyboard.instantiateViewControllerWithIdentifier("LoginViewController") as! LoginViewController
let nvc: UINavigationController = UINavigationController(rootViewController: loginViewController)
leftViewController.mainVC = nvc
let slideMenuController = SlideMenuController(mainViewController: nvc, leftMenuViewController: leftViewController)
SlideMenuOptions.contentViewScale = 1
SlideMenuOptions.hideStatusBar = false;
self.window?.rootViewController = slideMenuController
self.window?.makeKeyAndVisible()
return true
}
dont forget to add this variable in your LeftMenuViewController
var mainVC : UIViewController!
Below is my code, I am unable to load first view controller through this suggest me without using navigation controller embedded.
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
// Override point for customization after application launch.
let storyBoard = UIStoryboard(name: "Main", bundle: NSBundle.mainBundle())
let firstViewController = storyBoard.instantiateViewControllerWithIdentifier("LoginViewController")
self.window?.rootViewController = firstViewController
return true
}
1) make sure you are filling in the correct name for your storyboard.
2) check the identifier name for your view controller.
then,
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
self.window = UIWindow(frame: UIScreen.mainScreen().bounds)
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let initialViewController = storyboard.instantiateViewControllerWithIdentifier("LoginViewController") as UIViewController
self.window?.rootViewController = initialViewController
self.window?.makeKeyAndVisible()
return true
}
Do you need to do it via code? As your view controller is in storyboard you can just click on the view controller and tick the box to make it the initial view controller, which achieves the same thing as your code:
let storyBoard = UIStoryboard(name: "Main", bundle: NSBundle.mainBundle())
change here your storyboard name.
if you use storyboard, you gotta set the initial view controller in storyboard, "self.window?.rootViewController " won't work