How do i handle navigation Back button view hierarchy? - ios

Here is the problem
1) Rootview controller - MYAssetVC-> Embedded with NavigationController here pushing for button to another Addfilevc.
2) Addfilevc Has dropdownTextfield It will push to another vc have tableview selected row will display in the textfield.
3)if i select another value from the dropdown textfield it will push to the vc again there i will select.
Navigation bar back button will navigate to all my view hierarchy i want to handle this one. if i go to same view it should navigate back only once that to the recent visit how to do this.
As i am new to iOS. give any suggestion.
Navigation from 1->2->3
navigation backbtn 3->2->1
if i navigate like this 1->2->3-> backbutton 3->2 again 2->3 backbutton 3->2 again 2->3
IF i navigate now using back it is displaying all my route path it should navigate like 1->2->3> and 3->2->1 if any number of times i perform actions in 2 & 3.
1,2,3 are view controllers.

Create an IBAction for the back button and use popViewController.
[self.navigationController popViewControllerAnimated:YES];
This will help you to go back one page. You have to write this in all the pages where there is a back button and you want to go back one page.
If you want to go back directly to rootViewController, try this:
[self.navigationController popToRootViewControllerAnimated:YES];
And if you want to pop to any specific viewController in the stack, you run a for loop to find the viewController you want to navigate to and then simply popToViewController, like this:
for (UIViewController *viewController in self.navigationController.viewControllers) {
if ([viewController isKindOfClass:[Addfilevc class]]) {
[self.navigationController popToViewController:viewController animated:YES];
}
}
Hope this helps to clear your concept.
EDIT
In swift:
The [self.navigationController popViewControllerAnimated:YES]; will become self.navigationController?.popViewControllerAnimated(true)
The [self.navigationController popToRootViewControllerAnimated:YES]; will become navigationController?.popToRootViewControllerAnimated(true)
And the for loop will be as below:
You can use this if you are using storyboard
let switchViewController = self.storyboard?.instantiateViewControllerWithIdentifier("view2") as ComposeViewController
self.navigationController?.pushViewController(switchViewController, animated: true)
And the for-in loop
if let viewControllers = self.navigationController?.viewControllers {
for viewController in viewControllers {
self.navigationController!.popToViewController(viewController, animated: true);
}
}
Thanks.

Related

Not able to navigate to another UIViewController programmatically iOS

I am trying to navigate to "Home" view controller and for this I have written the following code in the ContainerViewController. But once the code executes, the application hangs and it show 100% CPU usage. Please help.
- (IBAction) home:(UIButton *)sender
{
HomeViewController *homeViewController = [self.storyboard instantiateViewControllerWithIdentifier:#"HomeViewController"];
[self.navigationController pushViewController:homeViewController animated:YES];
//[self presentViewController:homeViewController animated:YES completion:nil];
}
I have a question for you
1-If You want to push SecondViewController on to FirstViewController then your code is good enough
2-If you have a containerview in firstViewController and you want to add SecondViewcontroller's view to firstViewController
then use this code
UIViewController*vc1 = [[test1 alloc]initWithNibName:#"SecondViewController" bundle:nil];
//add to the container vc which is self
[self addChildViewController:vc1];
//the entry view (will be removed from it superview later by the api)
[self.view addSubview:vc1.view];
I think you want an unwind segue here. In your first view controller add :
- (IBAction)unwindToFirstViewController:(UIStoryboardSegue*)sender
{
}
You then need to hook up each of your view controllers home button to the green Exit button at the bottom of the view controller, choosing the unwindToMainMenu option. This will then take you back to the first view controller when pressed.
Have you tried popping the current view?
navigationController?.popViewControllerAnimated(true)
or just popping to root?
navigationController?.popToRootViewControllerAnimated(true)
or setting a new stack?
navigationController?.setViewControllers(homeViewController, animated: true)
The code is in Swift but it would work the same in ObjectiveC

Navigation bar back button change functionality

I have 3 view controllers: A, B and C. A is initial and it has 2 buttons: one is redirecting to B, and second one to C. When B is pushed, and button within B pressed user is redirected to C. Now on navigation bar within C, when I press back button I want to be redirected to A always, and never to B. Is that possible?
This is base functionality I want to achieve:
a)
A->B->C C back to A
b)
A->C C back to A
for (UIViewController *controller in self.navigationController.viewControllers)
{
if ([controller isKindOfClass:[A class]])
{
[self.navigationController popToViewController:controller
animated:YES];
break;
}
}
you can achieve this with presentview controller as modal view.first from a if first button is pressed present b view.if secnd button is pressed present c view and in c view controller put back button and add delegates and implement the delegate in a view controller.and you will have to dismiss one view after the other in a view controller.
The only way is replacing the back button by a custom button.
After reading what you said I think you meant implementing custom actions for each button.The way I would do it(In Swift) is this:
#IBAction func pressButton(sender : UIButton){
var SecondView :ViewController2
SecondView = self.storyboard?.instantiateViewControllerWithIdentifier("SecondView") as ViewController2
self.presentViewController(SecondView, animated: true, completion:nil)
self.viewWillDisappear(true)
}
This method I have used a lot and I know there is another way using segues but you still use #IBActions.You just create a new segue(identifier) and in the prepareforSegue method you say what happens when that segue is triggered

UINavigationController back button return to FIrstTableViewController

So I was create three UITableViewControllers with UINavigationController. I want a back button on 3rd UITableViewController, what returns my view to first UITableViewController instead of second.
How can I do that? That must be a real backButton, not a image or something else. Will be perfect to do this only with storyboard.
UPDATE
Perhaps I poorly explained what I want.
I don't want use any button with action on it. I just want something like as setting "address" of 1st TableViewController on my default back button. There is any way to do it?
add a button and connect it to following action
- (IBAction)backToFirstView:(UIButton *)sender
{
[self.navigationController popToRootViewControllerAnimated:YES];
(or)
[self.navigationController popToViewController:yourFirstViewControllerObject animated:YES];
}
There are different ways to navigate from DetailViewController to other view controllers.
We will go through the cases one by one.
First of all I would like to clear that if its your default
navigation bar's back button, then it must return to the last most
view controller only which is actually a default behavior of a
navigation controller.
Second, If you would like to go back to the
last most view controller on the tap of a button placed by you, you
should write the following code
[self.navigationController popToViewController:NAME_OF_A_VIEWCONTROLLER animated:YES];
Third, If you would like to go to the first view controller from where you
started, you should write the following code
[self.navigationController popToRootViewControllerAnimated:YES];
Ok, I found a way to resolve my problem. Thanks for your answers guys, they was very helpful.
So for resolve this problem you just need use link what give me Kumar KL upper, and wrote next method in your UITableVIewController
-(void) viewWillDisappear:(BOOL)animated {
if ([self.navigationController.viewControllers indexOfObject:self]==NSNotFound) {
// Navigation button was pressed. Do some stuff
[self.navigationController popViewControllerAnimated:NO];
}
[super viewWillDisappear:animated];
}
Now you got a backButton what redirect you to your viewController, BUT title of this button is wrong. Let's resolve that unfair.
Create new class CustomSegueцрфе inherited from UIStoryboardSegue with next code in CustomSegue.m :
- (void)perform
{
UIViewController *sourceView = (UIViewController *) self.sourceViewController;
UIViewController *destinationView = (UIViewController *) self.destinationViewController;
[[destinationView navigationItem] setTitle:#"TitleOfYourViewController" ] ;
[sourceView.navigationItem setTitle:#"TitleOfButton"] ;
[sourceView.navigationController pushViewController:destinationView animated:YES];
}
Now you can go to storyboard and connect 2nd ViewController with 3rd with custom segue.
Like you see UINavigationController uses Title of previous ViewController for button title, so you just need change it.

how to pop view from stack in tab bar controller in iOS

I have a tabbar controller. In one of the viewcontroller children I do a check and determine if I will show a login view with this code:
if(loggedIn){
}else{
SignupViewController *svc = [self.storyboard instantiateViewControllerWithIdentifier:#"SignupView"];
svc.hidesBottomBarWhenPushed = YES;
[self.navigationController pushViewController:svc animated:YES];
}
From here the user goes through several subsequent views in wizard format. Like from SignupViewController1->SignupViewController2->SignupViewController3->etc. As #Rocky pointed out, you cannot pop SignupViewController1 off the stack while you are in SignupViewController2 or 3 or any subsequent viewController.
I know the iOS docs state the following:
If YES, the bottom bar remains hidden until the view controller is
popped from the stack.
My question is how do I get acccess to the original SignupViewController to pop it off the stack to see my tabbar again once I have moved to subsequent views in its navigation controller?
(The next answer is for SWIFT, but, you can traduce it to Objective-C)
I do not know, but maybe you can try that:
#IBAction func returnToPreviusScene(sender : AnyObject) {
let navController:UINavigationController = self.navigationController!
navController.popViewControllerAnimated(true)
navController.pushViewController(FatherView.singleton, animated: false)
}
You need to know:
singleton is a static variable from the VIEW FatherView

Interface Builder IB - Navigation Controller, skipping a view

Hello I am new to iOS and have a question about navigating through my views.
I am using IB wiring up the PREVIOUS and NEXT buttons in the nav bar that pushes my views. This all works fine. However I am having trouble finding out where exactly what I need to do or where I need to place the code so I can skip over a view. To simplify my situation...
-I have 1 Nav Controller and 4 View Controllers named VC1, VC2, VC3, VC4. Each VC has a .H/.M
-Starting from VC1, they follow one after the other.
Say I want to skip VC3 and jump right to VC4 based on a setting in VC2. Where would I put the code to do this? Would I need to unhook the IBAction method from the NAV buttons at VC3?
I do apologize if this has been covered before. If there is a tut or if you know of a post that answers this, please let me know. I did do a search but the search was returning generic posts probably due to me using the wrong terminology.
Thanks in advance.
A couple of thoughts:
If you want to push from VC2 to either VC3 or to VC4, rather than having VC3 immediately push to VC4 in special cases, I think it's better to just have VC2 push directly to the appropriate view controller. Thus you might have an IBAction in VC2 that would do this for you:
- (IBAction)pushToNext:(id)sender
{
BOOL skipToVC4 = ... // put in whatever logic you'd use to bypass VC3 and go directly to VC4
UIViewController *nextController;
if (skipToVC4)
{
nextController = [self.storyboard instantiateViewControllerWithIdentifier:#"VC4"];
// obviously, if using NIBs, you'd do something like:
// nextController = [[ViewController4 alloc] initWithNibName:#"VC4" bundle:nil];
}
else
{
nextController = [self.storyboard instantiateViewControllerWithIdentifier:#"VC3"];
}
[self.navigationController pushViewController:nextController animated:YES];
}
This way, when you pop back from VC4, you'll pop back directly to the appropriate view controller (e.g. if you pushed from VC2 to VC4, when you pop, you'll pop right back to VC2 automatically.
And, obviously, if you're using storyboards, rather than manually invoking pushViewController, you could have two segues from VC2 (one to VC3 and one to VC4), give them appropriate identifiers, and then just invoke performSegueWithIdentifier to segue to the appropriate view controller. But the idea is the same: You can define an IBAction that performs the appropriate segue depending upon whatever logic you so choose.
You say that you have "PREVIOUS and NEXT buttons in the nav bar that pushes my views", I wonder about your "PREVIOUS" button. Is that doing a popViewControllerAnimated? Generally, a "NEXT" button will push to a new view controller, but the "PREVIOUS" button should not push to the previous view, but pop back to it. If you don't pop back, you can end up with multiple instances of some of your prior view controllers. Thus, the "PREVIOUS" button should be linked to an IBOutlet that does something like:
- (IBAction)popToPrevious:(id)sender
{
[self.navigationController popViewControllerAnimated:YES];
}
When popping back, you'll obviously pop back to the view controller that you pushed from. If you want to skip a few of the view controllers as you're popping back in iOS versions prior to 6.0, you would use popToViewController or popToRootViewControllerAnimated. For example, let's say that you pushed from VC1 to VC2, to VC3, to VC4. If you want to pop back from VC4 all the way to VC1, you would hook up and IBAction in VC4 like:
- (IBAction)popToRoot:(id)sender
{
[self.navigationController popToRootViewControllerAnimated:YES];
}
Or, if you wanted to pop back from VC4 to VC2, you would
- (IBAction)popToVC2:(id)sender
{
for (UIViewController *controller in self.navigationController.viewControllers)
{
if ([controller isKindOfClass:[ViewController2 class]])
{
[self.navigationController popToViewController:controller animated:YES];
return;
}
}
}
You can avoid this iteration through the navigationController.viewControllers if you passed a reference of VC2 to VC3 and then again to VC4, but sometimes the above technique is easier.
By the way, if you're supporting iOS 6 and above, only, and are using storyboards, you can also use unwind segues, which are a more elegant way of popping back to a particular view controller. But it's not clear whether (a) you're using storyboards; and (b) you're supporting iOS 6 and above only, so I'll refrain from a discussion of unwind segues at this point.
First:
Show us some code, where you are pushing new view controllers, maybe your whole navigation controller code
Second (Solution):
I assume:
Your prev/next buttons are linked to your navigationController class
you have the appropriate methods (prevPressed:/nextPressed:), which are called, when you click one of the buttons
I can help you with the following:
you know which controller is visible at the moment with the visibleViewController #property
each time you click on a button in the navBar you can ask the visibleViewController which next/previous view controller should be pushed/popped
Best solution would be, if all of your controllers VC1/2/3/4 are a subclass of a viewController class, which defines a method in it's interface:
- (Class)nextViewControllerClass;
- (Class)previousViewControllerClass;
and in the implementation:
- (Class)nextViewControllerClass {
return [VC4 class];
}
- (Class)previousViewControllerClass {
return [VC1 class];
}
And in your navigationController code the do this:
- (IBAction)next:(id)sender {
UIViewController *nextViewController = [[[self.visibleViewController nextViewControllerClass] alloc] init];
[self pushViewController:nextViewController animated:YES];
}

Resources