I am using a tabbar, each tab having a navigation controller, and this in turn having a stack of views. Each view is having its own view controller but this is not important now.
Lets have a tab 1 with a navigation controller 1 with views A, B, C.
The nature of the application dictates however that the view B is the primary one.
So what I want is that by default (after first or after relaunch of the app), when I tap the tab 1, I will see the B view together with the back button to A view.
How can I achieve this?
You can set up a delegate for your tab bar controller and implement tabBarController:didSelectViewController: to detect when someone taps a tab. If you detect that A is about to be selected and you want B to be displayed instead, you can tell A's controller to use its navigation controller to push B's controller.
Try initializing and pushing view B (without animation) onto the navigation stack in viewDidLoad of view A.
You could use the setViewControllers:animated: of UINavigationController.
Depending on your exact needs you could set this in your app delegate applicationWillEnterForeground: or applicationDidBecomeActive: methods.
I recall there being an Apple sample app that does exactly this. The general idea is to save the last visible view controller (or just hard code the one you want) and then push it to the visible state using something like so:
[myNavigationController pushViewController:viewControllerToBeVisible animate:NO];
You'd want to show the apps tabBarController:didSelectViewController:, and handle the different cases based on which viewController was selected.
Related
I am trying to do if user give correct password it will go back to the current last view controller where i was,like in Ios if u enter background in your app and after sometime you enter foreground then you will go back to the last view i.e where you was before entering background.please tell me how to implement this.
if you want to pop to the root controller you can use popToRootViewControllerAnimated.
[self.navigationController popToRootViewControllerAnimated:YES];
From Apple doc of UINavigationController
popToRootViewControllerAnimated:
Pops all the view controllers on the stack except the root view controller and updates the display.
- (NSArray *)popToRootViewControllerAnimated:(BOOL)animated
If you have set up a UINavigationController and its root controller is called A, then if you navigate from A to B and then from B to C you have two possibilities to come back to a previous controller (you can have others but I list the main ones):
navigate back from C to B with popViewControllerAnimated
navigate back from C to A with popToRootViewControllerAnimated
I would suggest using a modal view controller that is not actually added to you parent controllers hierarchy (child view controllers) and can be shown and dismissed at your discretion take a look here for a great example.
It seems like this should be easy to figure out, but I haven't had any luck this afternoon. I threw together this quick, simplified storyboard mockup of my problem.
Basically, I would like the table view controllers below to also be in a tab bar controller (in addition to the already present navigation controller). The tabs would switch between the two table view controllers.
Right now, the view controller with the buttons acts as a sort of menu. Each button leads to one of the table view controllers. Ideally this view controller would not have the tab bar visible, and would only be reachable from back buttons on the nav bars of the table view controllers.
I've tried a few different ways of embedding into a tabbarcontrollers but none of them produce the desired result:
-I've tried selecting both table view controllers and embedding those in a tab view controller. The tabbar doesnt show up in simulator, and the 'unreachable scene' warning appears.
-I've tried embedding the initial nav controller into a tabbarcontroller. This creates a tab entry for the first 'menu' page. It also causes issues with push segues once I connect the tableviews to the tabview.
I would be fine implementing some programmatic options on top of the storyboard, I just chose storyboarding for this project since it's a relatively simple presentation of data.
What is the proper way of going about this? Thanks!
A tab bar controller needs to be the root view controller of your view hierarchy. It goes against the HIG and Apple's standards to put a tab bar controller inside of any other type of container controller.
From the Apple docs:
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, the bottom line here is you need to rethink your design. One option would be to set the UITabBarController as the root view of your window, and then have each of your UITableViewControllers inside of a UINavigationController, which is placed inside of the UITabBarController. In this way, you still get the navigation bar, and stay within Apple's design guidelines (you also won't get those pesky warnings, and Apple may even be throwing an exception nowadays if you try to install a UITabBarController as anything other than the root view of the window).
I accept JMStone answer but we might get into situation where we need to put tab bar controller inside other controller especially table view controller.
Please refer Storyboard navigation controller and tab bar controller
and also the good example by Matthjin: http://cl.ly/VQLa
Hopes it help some one who want to put tab bar controller inside table view controller and wants proper navigation.
I've set up a really simple project using storyboards including two views as shown here: http://i.stack.imgur.com/iRx21.png. The navigation can be done by either selecting a cell in the custom table view or hitting the back button labelled with "<<". Everything works fine except the following:
when I switch between the views, every time an instantiation happens. The profiling shows an increasing number of view objects. I would like to keep only one of each view and instantiation should be happen only once. What am I doing wrong? (I'm using ARC.)
Thanks in advance!
You should not link your back button to the parent view controller. This is what causes the new instantiation.
The way to go is to embed the table view into UINavigationController (in IB, choose Editor -> Imbed In -> Navigation Controller. Then change your segue to a Push segue. You can of course hide the navigation bar etc. to make things look exactly as you like. Then, link the back button to the controller with an IBAction and in the handler do a simple
[self.navigationController popViewControllerAnimated:YES];
This would be the appropriate logic of what you are doing. Of course, you can also push the web view modally and then handle the button click with
[self dismissModalViewControllerAnimated:YES];
For my new app I'm planning to use UINavigationController to push/pop other controllers.
Here is the scenario.
Application is running. Via navigation controller I push first controller on the stack. The user make some selections and touch a button. Then navigation controller push the second controller and so on while the user reach the last controller which is sixth. Controllers from first until fifth will never be used again in the app.
Is this the correct approach (using navigation controller) for such kind of app ?
I am not entirely sure what you mean, but I guess you need to walk the user through step 1 to 5, then when they done at 6, they cannot go back. Is that correct?
I did something similar. What I did was pop up view 1-6 modally(and navigate from 1 to 6) to interrupt from the current flow, and once the user's done, the value got passed back to the view where you populate the modal view from(delegation) and then you do whatever next.
Not sure if i answered your question. Hope it helps.
If once they reach the 6th viewController they will never go back to the other viewControllers you can always pop to the rootViewController and then push the 6th viewController on. That way those other viewControllers are not in the navigationController stack.
It sounds like you have a flow of 5 linked screens, and then the rest of your app.
If so, yes, UINavigationController would work fine here. You would push those 5 screens, and when its done you would destroy the navigation controller and replace it with some view for the rest of your app.
So the UINavigationController would control one part of your app, but not your entire app.
I'm having trouble to achieve the following using a storyboard:
When setup is not done:
run app -> show settings view controller -> show main navigation controller
When setup is done:
run app -> show main navigation controller
So basically, I want the app to programmatically start with the settings view in certain cases, and otherwise skip right ahead to the main navigation controller.
I did manage to show the settings view with a modal style segue from the main navigation controller, but I don't know how to display it before the main navigation controller is displayed. Any ideas?
By default, the initial view controller from your main storyboard is instantiated and displayed automatically when your app starts up. To prevent this happening you need to remove the UIMainStoryboardFile setting from your info.plist file.
With no default view controller, you are now free to create one programmatically at app startup. See the UIStoryboard documentation. Use +storyboardWithName:bundle: to load the storyboard and then use –instantiateViewControllerWithIdentifier: to create the correct view controller. You will also need to create a main UIWindow and add the view controller's view to it just like you used to do with .nib based UI. Note that without the UIMainStoryboardFile setting a main window is not created for you - read the explanation.
I managed to do it a bit different:
Use a UINavigationController as the initial view controller.
Create a root view controller that will manage the decision of what to load.
Create a Storyboard Segues from the root view controller to the main view and to settings view, and give the segues proper identifiers.
Call the performSegueWithIdentifier with the proper identifier from your root view controller.
Just another solution, hope this helps.
I did something similar to amoshaviv, his advice is sound. I did it slightly different though, and I'll give some more info.
I created a custom MyInitialViewController class, derived from UIViewController, and made this the initial view controller.
In the storyboard file, I created modal segues with appropriate names to all (in my case three) possible 'real' first view controllers.
In the MyInitialViewController class, I implemented the
- (void)viewDidAppear:(BOOL)animated;
method, to first perform the check which view to switch to, and then do the correct
[self performSegueWithIdentifier:#"NameOfSegue" sender:self];
Effectively, this makes the MyInitialViewController nothing more than a switch performed when it's brought into view. I first tried doing this when loaded because I don't care for actually seeing this view, but that did not work, while viewDidAppear does.
To make this visually smooth, I tried the following. In the properties of the segues, I disabled animation. The view I left empty, and I gave it a background color matching to that of the startup image.