Using UISplitViewController in iOS - ios

I want to add a split view controller when the login button is clicked on the login screen (when user is successfully logged in). I want to show another view controller which is a split view controller with a master controller and detail controller.

SplitViewControllers are intended to be used as the root view controller. So you will need to create your login viewController and attach it to the window. Then when the user logs in you will have to remove the login viewController and then create a new SplitViewController and attach that to the window instead.
If you search you should find threads that help e.g.
How to implement SplitViewController on second level.?
I know there are also threads showing how to do this for tabBarControllers and the process is the same.

Related

UINavigationController limited utilization in app design

I am using the NavigationController (Embedded via Editor drop down menu in xCode) to control navigation on sign-up and sign-in views, all from landing view when app first launched.
After user sign-up or login, I would like to initiate a view controller with no relation to the NavigationController. Nonetheless, from Sign-up and Login views, I have a segue that links (upon successful authorization) to the main view of logged in users. How can I remove the navigation controller from a certain part of the application because it is no longer needed? Otherwise, each time I add a new view controller, it shows the navigation bar in it which is not ideal for design.
Thanks and image attached shows what I need illustrated.
As far as I am concerned you can remove only view controller from navigation stack. If you do not want navigation bar to be visible, then just hide it in viewWillAppear of view controller that you want to be without navigationBar.
[self.navigationController setNavigationBarHidden:<#(BOOL)#> animated:<#(BOOL)#>]

View Controller Setup

I am trying to figure out the best way to get my view controllers setup according to the design I am given. My app starts off with a full screen login screen. The user logs in and then the next view is a 3 tab screen. Where clicking on any control in any of the 3 tabbed view, need to take you to a full screen view controller.
Now the problem I am facing is that
1) The guidelines say not to put a TabBarController in a NavigationController, which in this case I have to do.
2) Also If I set the ViewControllers of each TabBarView to be a navigation controller, then I don't get the full screen space as the bottom always shows the tab bar, which I don't need to see.
Thoughts and pointers gladly appreciated.
The way that I would set it up would be to have a global container view controller that manages all of the internal view controllers. Example:
=============================
= Container View Controller =
=============================
| |
------------ -----------
- Login VC - - Main VC -
------------ -----------
Then, the workflow for app launch would be as follows:
Application launches and the container/splash view controller is the root view controller.
Container view controller determines login status (shows a loading indicator perhaps, etc).
Transition to the correct view controller.
If the user is not logged in, you could transition to the login view controller. From there, you could subscribe to either a delegate callback or a notification which would be dispatched once the user logs in. Once that message is received, you could re-check the login status and show the view controller accordingly.
If the user is logged in, at either the start or after receiving the login callback, then just show the main view controller.
Logout would work the same way as login. Just push a notification to the container view controller and have it manage the view controllers accordingly.
Personally, I would use a tabBarController as your initial view controller. If the user is not logged in, immediately present (modally) your login view controller. Dismiss the login controller once the user has logged in, and return to the tabBarController. Wrap the view controllers for each tab in a navigation controllers, but set hidesBottomBarWhenPushed in order to hide the tabBar.

How to skip a login view controller?

I develop an iOS app and my initial view controller shows a login form. Then when the user successfully authenticates the actual application is presented as a modal view controller.
When the user logs out the application it is dismissed and the login view controller is visible again.
My problem is:
When the application is started again and the user already is logged in I don't want to show the login view controller. I can't present the view controller before the login view controller is fully shown:
Warning: Attempt to present <UITabBarController: 0x10a271b40> on <LoginViewController: 0x10a2594f0> whose view is not in the window hierarchy!
I can present it with a delay but this is not what I want.
I could check if the user is logged in before I show a view (in the app delegate) and then show the login or the application. The problem with this is:
When the user logs out I have no login view controller beneath my application to which I can pop.
I can't find a good solution except defining the actual application as the root and present the login over it. But this brings a lot new problems because the main application needs data structures I can only initialize after login.
You don't want to be running with a modal always shown, it will be easy to inadvertently dismiss your 'entire app'.
Instead, do as you suggest in the app delegate where you decide which view controller is required and change the root view controller of the window. Again, when the user logs in / out, change the windows root view controller.
Most Application flow will be like that.
1) Set your tabbar controller as rootviewcontroller. When application launch, check with login status and show your tabbar(rootviewcontroller) if already logged in. Otherwise present modal view as loginview controller from tabbar(tabbar is rootviewcontroller).
2) When logout success, again show loginView as modal view(tabbar is rootviewcontroller).
Note: You can also shift rootviewcontroller as tabbar and loginview. But I recommented above flow.

Starting app with login page when tab bar controller is present

I have conditional code in my app delegate's didFinishLaunchingWithOptions: method that uses HTTP requests/responses to determine if the user is logged in already. I'm running into serious hierarchy problems, and my question is this: should I be starting my app with the login page (and make the app delegate conditionally load my tab bar when the user is logged in already), or start with my tab bar (and make the app delegate conditionally load my login page)?
This is my storyboard currently
I would make the tab bar controller the root view controller of the window, and present the login controller from the viewDidAppear method (without animation) of the controller in the first tab. Also, you should not go backwards in a storyboard with a segue, unless you use an unwind segue. Segues (other than unwinds) alway instantiate new controllers, so you're not actually going back to a previous controller, you're instantiating a new one. This will cause more and more controllers to be added to your hierarchy as the user navigates back and forth.

About tab bar using storyboard

I want to create an app using storyboard that has login window and tab bar controller.
So the flow will be upon tapping the login button, the app will be redirected to tab bar controller with its views.
I have done this:
But referring to Apple Documentation: UITabBarController
Because the UITabBarController class inherits from the
UIViewController class, tab bar controllers have their own view that
is accessible through the view property. When deploying a tab bar
interface, you must install this view as the root of your window.
Unlike other view controllers, a tab bar interface should never be
installed as a child of another view controller.
So that means I am not allowed to do so?
In addition:
The 3 views that are referred by my tab bar, then each of them has their own child view again, but the tab bar in the child view is gone. What could be happen? Am I missing something?
What I have done in all my apps that are structured similarly is to have the first view controller check for valid authentication and if that fails, present a login VC. That login VC has a delegate defined that will pass back the user credential after a successful login and then dismisses the modal login VC does whatever.
Here is a sample layout:
The delegate protocol looks like this:
#protocol LoginViewControllerDelegate
-(void)finishedLoadingUserInfo:(UserInfo *)curUser;
#end
Where UserInfo is the model I use for the user information (in my case, NetworkID, FullName, etc).
When the user has successfully authenticated, I fire off that delegate method which is handled in the class that presented it. If you need more detail, I can help - but the process is simple.
You can launch your login screen first from the appDelegate and then setup and launch the tabBarViewController after the login is successful.
An alternative design is to do the following steps:
1. set up your tabBarViewController,
2. disable the tabs,
3. launch your login view controller modally,
4. enable tabViewController tabs
Either of these two approaches should work.

Resources