Initial view controller and Tab View Controller - ios

I'm working with a single view app but also I'm using Tab View controller at one case , but the Tab view Controller must be put as initial view controller to work so how I can use Tab view controller without make it as initial view Controller?

#SamahAhmed
let storyboard = UIStoryboard.init(name: "Main", bundle: nil)
let diallerTBC = storyboard.instantiateViewControllerWithIdentifier("tabBarStoryboardId") as! MyTabbarController
//create a variable for e.g : data at MyTabbarController and set like
diallerTBC.data = "testing"

When you are clicking on button to move tabbar controller
Provide a storyboard id to tabbar and use below code
Write this as a class method in appdelegate and call it on button click
let storyboard = UIStoryboard.init(name: "Main", bundle: nil)
let diallerTBC = storyboard.instantiateViewControllerWithIdentifier("tabBarStoryboardId") as! UITabBarController
self.window?.rootViewController = diallerTBC
self.window?.makeKeyAndVisible()
}
I hope this will work
Thanks

Related

How to open specific ViewController from TabBarController

Sorry, if it is an essential question.
The scheme is the following:
enter image description here
I want the following:
User taps last Tab
User goes to some ViewController (different from ViewController, actually connected with last Tab)
How to do this (without using segue)?
Thanks a lot in advance!
You can go with instantiateViewController with push when load your tab and push one viewController to another like below:
let next = self.storyboard?.instantiateViewController(withIdentifier: "nextVC")as! nextVC
self.navigationController?.pushViewController(next, animated: true)
You can assign ViewController in you UITabBarController
let storyboard = UIStoryboard(name: "Main", bundle: nil)
// create view controllers from storyboard
// Make sure you set Storyboard ID for both the viewcontrollers in
// Interface Builder -> Identitiy Inspector -> Storyboard ID
let clockViewController = storyboard.instantiateViewControllerWithIdentifier("ClockViewController")
let stopWatchViewController = storyboard.instantiateViewControllerWithIdentifier("StopWatchViewController")
// Set up the Tab Bar Controller to have two tabs
let tabBarController = UITabBarController()
tabBarController.viewControllers = [clockViewController, stopWatchViewController]
// Make the Tab Bar Controller the root view controller
window?.rootViewController = tabBarController

Navigate to a specific View Controller inside a TabBarController from AppDelegate, Swift

I have a TabBarController with two tabs Cases & Settings
I would like to take the user to CaseSummaryTVC which is nested like this
TabBarController > Cases (NavigationController, Storyboard Id = 'tvcNav' ) > CasesTVC (TableViewController) > CaseSummaryTVC (TableViewController, Storyboard Id = 'CaseSummaryTVC').
I am using the below code in AppDelegate, which takes me to the 'CaseSummaryTVC' but doesn't show the TabBar on the bottom.
let mainStoryboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let navController = mainStoryboard.instantiateViewController(withIdentifier: "tvcNav") as! UINavigationController
let caseSummaryTVC = mainStoryboard.instantiateViewController(withIdentifier: "CaseSummaryTVC") as! CaseSummaryTVC
navController.pushViewController(caseSummaryTVC, animated: true)
self.window?.rootViewController = navController
self.window?.makeKeyAndVisible()
It looks like you're setting your window's rootViewController to be 'navController', which doesn't seem to be wrapped in a UITabBarController.
I'm not sure what your storyboard looks like, but it sounds like you have the view hierarchy setup correctly there.
You could do one of the following:
1) Remove the programmatic view controller instantiation and have the storyboard take care of setting the rootViewController to the UITabBarController.
2) Instantiate the UITabBarController programmatically like you have done here with the other view controllers, and make sure it's set up to have the navController as one of it's tabs.

Is there a way to assign the rootViewController of a NavigationController?

Is there a way to change root controller when someone is midway into using the app? The way I have it set up right now is that if a new user uses the app they will go into a login page that has the embedded navigation controller. When the user fills out the information they go onto the next page to confirm. The embedded navigation is to go back and change any info. Once they confirm they go to the main page. Now the issue is that the app goes to a different view that already has a Navigation Controller when the user returns and follows some logic. How do I assign the returning user navigation controller when the new user gets into that section? When the user presses back while they are on the blank view they will go back to the confirmation page.
How do I have the confirmation page view get the navigation controller on the top and not the bottom? I'm not sure where to change the Root Navigation Controller but I assume it should be in the prepareForSegue in Confirmation View Controller
if segue.identifier == "showMemoryTable" {
let memoryListVC = segue.destination as? ReturningUserCityDetailTableViewController
memoryListVC?.userData = userData
if userData?.newUser == true {
let newRootViewController = ReturningUserCityTableViewController()
self.navigationController?.viewControllers.first = newRootViewController
let mainStoryBoard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let viewController: UIViewController = mainStoryBoard.instantiateViewController(withIdentifier: "homeVC")
navigationController?.setViewControllers([viewController], animated: true)
}
I am not sure if I should use setViewControllers but I believe so
If you are aiming to Change the root view controller, you should not do it by by performing a segue, it would be more appropriate to do it like this:
let mainStoryboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let newRootViewController = mainStoryboard.instantiateViewController(withIdentifier: "ReturningUserCityTableViewController") as! ReturningUserCityTableViewController()
let ad = UIApplication.shared.delegate as! AppDelegate
ad.window?.rootViewController = newRootViewController
Note that it changes the whole app root view controller; You could set the desired navigation controller to be the root of the app (obviously you could get them by their storyboard ID).

How to change the initial view controller of storyboard?

I have 2 view controller ,and I disabled the initial view controller of first view controller ,and enabled the second view controller,but when start the project,the initial view controller is still the first view controller ,what should I do? Thanks!
Tap the second view controller, and select "Is initial View Controller" in Attributes inspector.
Alternatively you can do this with code too.
In your AppDelegate class's didFinishLaunchingWithOptions method you can write
let storyBoard = UIStoryboard(name: "Main", bundle: nil)
let secondVC = storyBoard.instantiateViewControllerWithIdentifier("SecondViewController") as! SecondViewController
self.window?.rootViewController = secondVC
Edit Swift 3.0
let storyBoard = UIStoryboard(name: "Main", bundle: nil)
let secondVC = storyBoard.instantiateViewController(withIdentifier: "SecondViewController") as! SecondViewController
self.window?.rootViewController = secondVC
Assuming that your storyboard name is Main.Storyboard and your SecondViewController Storyboard ID and Restoration ID is also set in Identity Inspector and use Storyboard ID is checked.
If you are starter like me ( both iOS and OSX mechine ) and you wanted to change the entry point within same storyboard, then,
-> long press on the entry point arrow.
-> drag it to the view controller you wish to make the starting point, the arrow will now move to your new screen.

Best way to conditionally switch root view controller at iOS app start-up

New iOS developer here. I am working on a project which requires that the user log-in when they first open the app. From then on, I want the app to open directly to the main flow of the app (a tab bar controller in my case). After doing some research, I have come across what seems to be two main ways to do implement this functionality:
1) Conditionally set the root view controller of the app's window in the app delegate. For example:
if userLoggedIn {
let storyboard: UIStoryboard = UIStoryboard(name: "Main", bundle: NSBundle.mainBundle())
let tabBarController: UITabBarController = storyboard.instantiateViewControllerWithIdentifier("TabBarController") as! UITabBarController
self.window?.makeKeyAndVisible()
self.window?.rootViewController = tabBarController
} else {
let storyboard: UIStoryboard = UIStoryboard(name: "Main", bundle: NSBundle.mainBundle())
let logInViewController: LogInViewController = storyboard.instantiateViewControllerWithIdentifier("LogInViewController") as! LogInViewController
self.window?.makeKeyAndVisible()
self.window?.rootViewController = logInViewController
}
2) Use a navigation controller as the app's root view controller, and conditionally set the view controllers managed by the navigation controller in the app delegate. For example:
if userLoggedIn {
let storyboard: UIStoryboard = UIStoryboard(name: "Main", bundle: NSBundle.mainBundle())
let tabBarController: UITabBarController = storyboard.instantiateViewControllerWithIdentifier("TabBarController") as! UITabBarController
let navigationController = self.window?.rootViewController as! UINavigationController
navigationController.navigationBarHidden = true
navigationController.setViewControllers([tabBarController], animated: true)
} else {
let storyboard: UIStoryboard = UIStoryboard(name: "Main", bundle: NSBundle.mainBundle())
let tabBarController: ViewController = storyboard.instantiateViewControllerWithIdentifier("LoginViewController") as! ViewController
let navigationController = self.window?.rootViewController as! UINavigationController
navigationController.navigationBarHidden = true
navigationController.setViewControllers([tabBarController], animated: true)
}
If I go with the second option, I can easily transition to the app's main flow (let's say a tab bar controller) after I'm done logging in the user. In an appropriate place in the LogInViewController, I can say:
// Transition to tab bar controller
let storyboard: UIStoryboard = UIStoryboard(name: "Main", bundle: NSBundle.mainBundle())
let tabBarController: UITabBarController = storyboard.instantiateViewControllerWithIdentifier("TabBarController") as! UITabBarController
self.navigationController?.setViewControllers([tabBarController], animated: true)
Pretty easy.
As for the first method, I am not sure how I would transition to the main content of the app after logging the user in.
What I am looking for here is the "best" way to handle login flow. I've listed two methods but maybe there is another that is even better. Also, if the "best" method is the first I have listed, how can I get to my tab bar controller after I finish logging the user in? Thanks!
Those are both fine options. One thing that I've done that has worked well is implemented a custom container view controller as the root of my app (this might be a subclass of my main view controller like a tab bar controller or navigation controller).
In this container view controller, I can put code to display and dismiss a login view controller based on the user's login status. Note: you can also use temporary full-screen views here to hide your app's main content while the login screen is shown/dismissed - this is an easy way to get very smooth app launch transitions.
I particularly like this method, because the rest of the app doesn't need to worry about the details. Your container can act like a normal tab bar controller or navigation controller, but underneath, you get to encapsulate all of the login UI logic in one place.

Resources