Set initial view controller of a navigation controller - ios

I'm developing a simple iOS app to learn Swift and iOS programming.
I was wondering what would be the "best" way to present, on app launch, a different View Controller than the first one in the Navigation Controller stack.
Consider this storyboard diagram:
The Tab Bar Controller is the initial View controller and "View Controller 1" is shown at app launch inside the navigation controller. Since "View Controller 1" will be almost never used, I'd like to show "View Controller 2" instead, with the "back" button pointing to "View Controller 1". To save time and memory, I'd prefer non to load "View Controller 1" at all, since I already know what data has to be shown in the second view controller.
Both the view controllers are actually Table View Controllers and the selection of one of the cells in the first VC triggers a segue to the second. However the user would usually only need to see the second VC as if the first cell of TVC 1 was selected.

Because you want to be able to "go back" to the first VC, it needs to be put below the second one. My suggestion is to programatically set up the first VC as the root view controller in appDelegate didFinishLaunchingWithOptions and immediately push/present VC2. In this way the first VC won't be shown and therefore costly views loading/laying out subviews can be omitted.

Related

Launch a viewcontroller in a stack of tabbar controller from background (iOS-Swift)

I have a storyboard with tab bar controller and one of the tabs segue to another view controller and so on as show in the picture.
I want to go to the page (3) programmatically in the stack while maintaining the stack of the tab bar controller .
Thanks in advance..enter image description here
This one's a little tricky, maybe someone else here knows a better way of doing it but here's how I would tackle the problem. Let's assume for simplicity that all views are loaded already. Let me know if this works
Setup an observer in the view controller that is being displayed by the tab selected in the tab bar controller. (Let's call this page TabPageVC). When the event that the TabPageVC is observing is fired have it segue way to page 3 immediately
In app delegate when the app becomes active / enters foreground check to see if you need to display page 3. If you do need to then get the root view controller in app delegate (i'm assuming it's the tab bar view controller, if it's not you'll need to set it to be).
Set the selected tab in the tab bar controller to be the tab of the index that TabPageVC lives in
Trigger that event that TabBarVC is observing this will cause TabBarVC to immediately segue way to page 3 and you'll have retained the stack

How do I jump to say, the second view controller in my navigation controller at app launch?

Like many apps, I have a main screen in my app that I want the app to launch to, but they also have the option of going back a screen to somewhat of a "home" view. I don't want to present this modally, as it is technically "before" the view controller they launch at.
So if my navigation controller has this first "home" view controller, then the "main" view controller after that (then some others after that...) how do I start the app at the second, main view controller and still allow them to easily press back to go home?
I tried setting my "Initial view controller" in my Storyboard to the second one, but it doesn't seem to work as it doesn't show the navigation bar and seemingly won't allow you to go back.
I'd recommend setting the "home" view controller as the "Initial view controller", but then segueing to the "main" view controller in the viewDidLoad or viewWillAppear of your "home" view controller; that way, unlike in Mike's answer, you can dismiss that "main" view and go back to the "home" view before it such that it's the only view controller on the stack.
You should make the second viewController the initial view, then make a UIBarButton on the second viewController, to let the user go back.

NavBar doesn't appear when segue is called programmatically

I have an iOS app with 3 views. I am using a "push segue" to move between them. I have linked a push segue from a button in First view to Second View. For moving from second to third, I cannot have a button. I have a list of items and the person can click in any of those to move to third(and last) view. So I added a segue in storyboard and calls it programmatically. The third view is opening properly except that the nav-bar is no longer there.
[self performSegueWithIdentifier: #"moveToFilesSegue" sender: self];
I can live without nav-bar. But the real problem is that I cannot do a push segue from my third view to any other view.
So my question is whether there is a way to call a segue from second view to third view in such a way that the third view also has the navigation controller that the first two have by default(ie navbar is also visible in third segue). There is some break in navigation because of me calling a segue programmatically.
So a few comments. If you would like to be able to get to the two other views from any view at any point in time, then I would suggest using a tab bar controller rather than a navigation controller.
If you must use a navigation controller, then you should keep the first view controller as the root view controller. Imagine then tapping a button that pushes the second view controller. Then say you tap a button to get to the third view controller from the second. What you should really do is perform an unwind segue from the second and then immediately perform a segue to the third. The animations will be a bit undesirable by default since it will probably show the pop and the push, but to treat it like a tab bar, you could just disable the animations on the pop and push.
To implement, keep an int variable in the first view controller (btw.. you can do this by keeping the int in the navigation controller as well if you want). In the viewDidAppear, check the int variable. If it == 1 then push the second view controller. If it == 2, then push the third view controller. Else, don't do anything. When a button is pushed in the second view controller to view the third, unwind the second view controller, but in prepareForSegue set the int variable in the destination view controller to 2 . Thus, when the first view controller appears, it will immediately push the third view controller.
I know it is a bit annoying, but you don't really want to keep pushing the same view controllers over and over again without unwinding.

Creating an initial view before displaying views with UITabController

I am creating an app that uses a UITabController with 5 tabs for navigation. Right now my app loads the first tab as the initial view upon app loading.
I want to be able to change that so I have a view that doesn't use my UITabController as the initial view, and once they click the one button on it, it brings them to the First View and displays the TabController.
I thought I'd simply set up a new view, change that one to the initial view controller and have a segue from the button to the TabController, but when I tried that and the view I wanted to with the button loaded first, but when clicking button it said something about needing to set up a NavigationController? Not sure what to do from here.
I think it's best to leave your tab bar controller as the window's root view controller. You can present the initial view controller from the viewDidAppear method of the controller in the first tab, using presentViewController:animated:completion:. Do this with the animated parameter set to NO, and the initial view will be the first thing the user sees. When you're done with that view, just dismiss it, and you'll be back to the first tab's view.

How to model different initial screen on app launch depending upon state with storyboards?

Whenever my app launches one of 3 possible screens will be displayed depending upon the state.
I was going to model this in a storyboard by having the starting view controller as a navigation view controller, then have a segue from it to each of the three other VCs.
Then on app launch the appropriate VC would get pushed depending upon the app's stored state.
However IB will not permit me to make multiple connections from the navigation controller.
If I make an initial segue from the NVC to any of the VCs, say A. Then when I attempt to add another segue from the NVC to another of the VC, B, then instead IB creates a connection between A and B.
First of all is the approach of having a Navigation Controller as a starting RVC and pushing different VCs onto depending on state an incorrect approach? If not, then how to model it with storyboards? Why will IB not let me drag and drop the segue to the other controller?
I don't think the navigation controller is the way to go. IB won't let you connect more than one, because that first connection is the root view controller, and there is only one of those.
There a many different ways you could get what you want depending on where you go after one of those 3 initial views. Do they all go to the same view next? All different view? Some the same, some different? It's hard to advise you without more detail.
You could start off with a tab bar controller, with the tab bar hidden, if you don't want that look. Or, you could have logic in the viewDidAppear method of a common initial controller, and have it switch the root view controller of the window to on of your three screens.

Resources