Push view to navigation from modal of another tab - ios

I'm quite new to iOS programming and I'm trying to do something that I think is simple but I can't find clear explanation.
I'm trying to develop an app with Xcode 6.3 and swift 1.2
I have this :
So I'm in a tab based application. Each tab view are inside navigation controller.
D is a modal launch from C. When I click on a button inside D I want to go to B. This is fine. But I would like also to display the top navigation bar with a back button pointing to A.
For now when I tried to use the push segue from D to B, B is shown as modal but not part of the navigation controller.
How I have to achieve this easily ? Do I have to recreate all the stack by instantiating each view (A then B) and push everything onto the navigation stack ?
If you know the code to achieve this in objective-c it's fine for me as well.

When I click on a button inside D I want to go to B. This is fine. But I would like also to display the top navigation bar with a back button pointing to A.
You can only go back to A, if it is actually on the navigation stack. So, you will have to somehow push it onto the stack before you can achieve your goal.
As a general hint, if you want a view controller to show the navigation bar, you only have to make sure it's embedded into a navigation controller. When you present a view modally, it will not by default be embedded into a navigation controller. So, as you said D is shown modally from C, just embed D into another navigation controller and instead of making D the destination for the modal segue, make the navigation controller the destination.
Update
If you want to show a back button in B that points to A, even though B was shown modally from D, you will have to hack your way around because A is not on the navigation stack. So, logically, what you have to do is make sure that A is on the navigation stack just before B. I don't think you can do this simply with segues from IB, but rather use code and instantiate the UINavigationController yourself:
- (void)showBModallyWithBackButtonToA
{
A *a = [[A alloc] init];
UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:a];
B *b = [[B alloc] init];
[nav pushViewController:b animated:NO];
[self presentViewController:nav animated:YES completion:nil];
}
This code has to be executed from D, if I understand your setup correctly.

Here is the solution from nburk converted in swift with the use of storyboard :
let a = UIStoryboard(name: "Main", bundle: nil).instantiateViewControllerWithIdentifier("aIdentifier") as! ATableViewController
let nav = UINavigationController(rootViewController: a)
let b = UIStoryboard(name: "Main", bundle: nil).instantiateViewControllerWithIdentifier("bIdentifier") as! BViewController
// b parameters here
// b.parameter1 = variable
nav.pushViewController(b, animated:false)
self.presentViewController(nav, animated:true, completion:nil)
Where aIdentifier and bIdentifier are the identifier you set inside storyboard editor for each view and ATableViewController and BViewController their respective ViewController classes.

Related

Opening a navigation controller from Tabbar with back button on first ViewController

I know this question has been asked so many times on the SO, but I am asking this just because it is relevantly different and also some answers are out dated and some are in Objective-c which I can not understand properly.
USE CASE:
I have a UITabBar controller, and it is working fine. Let say I have 4 tabs in it and user click on the button given in the Tab 4. now on it I have to open some series of View Controllers. let say User has following patteren to follow.
4.A-->4.B--> 4.C and can go back to first like so: 4.C-->4.B-->4.A
And finally User must also be allowed to go back to Tab4 after closing 4.A view controller
WHAT I DID:
I am able to open the View controller using this code.
let VC1 = storyboard.instantiateViewController(withIdentifier :"myVcId") as! UIViewController
let navController = UINavigationController(rootViewController: VC1) // Creating a navigation controller with VC1 at the root of the navigation stack.
self.present(navController, animated:true, completion: nil)
This is opening a navigation controller and having me navigate the view controller as per my requirements but I want following thing too
WHAT I WANT: As I am presenting the Navigation Controller modally, I want to show the back button at very first view controller, and I want that if user select back button it kills all the Navigation controller and go the previous view controller where he came from
You need to select the 4th tab and embed it inside a navigation then do
let vc = storyboard.instantiateViewController(withIdentifier :"myVcId") as! UIViewController
self.navigationController?.pushViewController(vc, animated: true)
then you'll see a back on that first vc , to return to that tab do
self.navigationController?.popToRootViewController(animated: true)
As far as I understood, your structure looks like this:
A TabBarController, with ViewControllers as tabs, and from them you present a navigation controller with other ViewControllers, like this:
(TabBar) -vc-> (View) -present-> (NavController) -root-vc-> (View)
I have two suggestions for making it easier to handle.
First option
Use navigation controllers as tabs for your TabBarController, and make your ViewControllers that are tabs their root view controllers.
(TabBar) -vc-> (NavController) -root-vc-> (View) -push-> (View)
Second option
Another option is to use a navigation controller as your initial view controller, and make your tab bar this navigation controller's root view controller.
(NavController) -root-vc-> (TabBar) -view-> (View) -push-> (View)
Both options should work, and the first one should be a little easier to handle.
You need to instantiate the navigationController with 4A as the rootViewController.
Then, in the viewDidLoad for 4A, you need to instantiate 4B, and push it to your navigationController.
Then, finally, in your 4B viewController's viewDidLoad you need to instantiate 4C and push it to your navigationController's stack.
P.S.: Push all the viewControllers without animations.
This should be achieving your strange scenario.
EDITED:
You need your 4th tab from your tabBar to be a navigationController,
and its root view Controller to be the initial VC which will then push
your new navController, otherwise you won't have the back button.
So, your stack should be something like this:
4CVC
|-(push)
4BVC
|-(push)
4AVC
|-(push)
newNavController
|-(push)
someVC
|
navController
|
tab1 tab2 tab3 tab4
|
tabBar

PresentViewController to a ViewController with a different NavigationController but on the same storyboard

I'm having trouble with a simple Xamarin Studio Storyboards concept. See screenshots below for visuals and see the downloadable source code here.
Let's say I have a NavigationController with MainViewController on it. This is visible in my storyboard. I want a button which, when pressed, brings up a new NavigationController with RedViewController. I also want RedViewController on the same storyboard as the MainViewController. In this project, I tried to do that but for some reason when I do a:
var myStoryboard = AppDelegate.Storyboard;
// Instatiating View Controller with Storyboard ID 'StuffViewController'
RedViewController = myStoryboard.InstantiateViewController ("RedViewController") as RedViewController;
RedViewController.ModalTransitionStyle = UIModalTransitionStyle.CoverVertical;
this.PresentViewController(RedViewController, true, null);
the RedViewController doesn't have it's Navigation controller with it. When presented RedViewController's Navigation Controller is null! What am I doing wrong there?
Now when I created a NavigationController & BlueViewController in a totally seperate storyboard it works fine. When I press the Blue Button it goes to the BlueViewController and correctly shows it's NavigationController. Why is this one working but the other one not? The only difference that I can see is that they are on separate Storyboards.
UIStoryboard storyBoard = UIStoryboard.FromName ("BlueStoryboard", null);
UIViewController controller = storyBoard.InstantiateInitialViewController () as UIViewController;
controller.ModalTransitionStyle = UIModalTransitionStyle.CoverVertical;
this.PresentViewController (controller, true, null);
ViewController that can present a new NavigationController & ViewController ViewController called "Red" with a navigation bar
When you instantiate your new view controller you need to instantiate the UINavigationController, not the RedViewController.
In the case of your 'blue' code you instantiate the initialViewController - which is the navigation controller that contains the Blue controller.
You want
RedViewNavigationController = myStoryboard.InstantiateViewController ("RedViewNavigationController") as UINavigationController;
where 'RedViewNavigationController' is the identifier for the navigation controller that the Red View Controller is embedded in.
If you want to present the red controller with its navigation controller, you should instantiate the navigation controller (which, in turn, will instantiate the red controller), and present it.

How to jump to any other controller in iOS?

My storyboard structure is like:
A is a navigation controller
B is a tab bar controller
C,D,E are view controllers
F,G,H,I,J are a view controllers
if now i am on I ,and there's a button the i pressed then I go back to C.How to do that?
I tried make segue between I and C, but C has a back button, you pressed it,you back to I.
I don't want that.when i came from I to C, i want C is as I first come to C from B.
if i want to go to H from I,I want H have a back button that you pressed and you back to F not to I.
From I to C: do popViewController twice, or loop through the navigationcontroller's viewcontrollers and find C, pop to C.
From H to I: Programmatically push to I. In storyboard set an storyboard ID for I, and you can create a I instance through [storyboard instantiateViewControllerWithIdentifier:ID];
I would set the viewControllers property of UINavigationController.
Create an array of View Controllers like you would desire the stack to be. Example: #{C, F, I} or in the case of your question you would use #{ C } then update the navigationController to contain these views.
[self.navigationController setViewControllers:(NSArray *)];
If you want to do something other than what your Segues are set up for, be sure to give your VC a stoyboard ID
Then using that storyboard ID, you can call this code to create/display;
-(IBAction)myButtonAction:(id)sender{
RDLaunchOptionsTableViewController *vc = [self.storyboard instantiateViewControllerWithIdentifier:#"RDLaunchOptionsTableViewController"];
vc.delegate = self;
[self.navigationController pushViewController:vc animated:YES];
}
You don't have to use a nav controller. Just use [self presentViewController....];

Pushing a view controller onto a navigation controller from a tab bar button

I have a tab bar controller with a button like so:
- (void) addButtonPressed:(UIButton *) sender
{
[sender setBackgroundColor:[UIColor regularColor]];
PostViewController *post = [[PostViewController alloc] init];
[self.navigationController pushViewController:post animated:YES];
}
This code runs but the PostViewController is never shown and the tab bar controller remains.
How do I get to push to a new controller?
The NavigationController was created and StartViewController was add as rootController.
Then in StartViewController I have:
TabBarController *tab = [[TabBarController alloc] init];
// Presentation
[self presentViewController:tab animated:NO completion:nil];
in tab bar you need to create separate Navigation Controllers.
Suppose there are 3 tabs A, B and C. All the three tabs have functionality of navigation from one view to another. than you need to create three separate Navigation controllers eact pointing to Tab A, B and C. In this way you can navigate to any class within the specific Tab.
Check out this link for more details.
Hope this will help you. Happy coding :)
You may need to embed your tab bar controller within a navigation controller, In your storyboard click on your tabbarController so that it is highlighted with all the blue lines and then go to Editor in Xcode choose embed IN> UINavigationController ..If you want to do it programatically then in your AppDelegate where you setup your Window just Use This::
UINavigationController* navigationController = [[UINavigationController alloc] initWithRootViewController:tabBarController];
navigationController.toolbarHidden=YES;
navigationController.navigationBarHidden=YES;
self.window.rootViewController =navigationController;
if you are using .xib then you have to use NSBundle to load nib
if you are using storyboard then you need to use prepareForSegue to pass on data or just display it out

Push to root View controller in UIStoryboard

I have hierarchy of ViewControllers in my storyboard structure.
It is A-B-C-D. A is embed with NavigationController and the flow goes on till D viewController. All fours view attached through segues. Now I am on D viewController, I defined some action to the button of D that It should take me directly to A viewController that is rootViewController or B viewController. Then how can I achieve this. I tried everything but didn't succeed.
I want something like it should not disturb A-B-C-D flow and it should take me to A viewController from D.
Right click on your D viewcontroller and drag i to your A viewcontroller.
Then click on the object which appears on the line you just created.
Write something like DtoA in the storyboard segue identifier in the attributes inspector.
Now in D view controller, just do:
[self performSegueWithIdentifier:#"DtoA" sender:self];
And if you instead wish to pop to a previous viewcontroller the old fashioned way, like from D to B:
UINavigationController* navController = self.navigationController;
UIViewController* Bviewcontroller = [navController.viewControllers objectAtIndex:1];
[navController popToViewController:controller animated:YES];
I hope this helps!

Resources