I have 3 view controllers: VC1,VC2, VC3.
The navigation is made pushing viewcontrollers (forward) like this: VC1 -> VC2 -> VC3.
Now once I an in VC3, pressing a button I want to go back to VC1 (not VC2).
If I use a pop I'd go into VC2, but how would I go directly from VC3 into VC1? (Like poping twice...)
Sounds like what you want is an popToViewController:.
Take a look a this solution: Can i pop to Specific ViewController?
Related
I have a View Controller (1) that lists some entities in a table. If the user wants to add a new entity they click and "add" button where they segue to VC2 (a view containing a form to fill in the necessary fields to add a new entity). After they add an entity at VC2 I want them to be automatically forwarded to the details screen VC3 related to the entity that they just added. Normally this detail screen VC3 is a segue from VC1 when they click on an existing entity from the table.
currently in VC2 I have
//go back to VC1
navigationController?.popViewController(animated: true)
//Segue to VC3
VC1?.performSegue(withIdentifier: "goToDetail", sender: self)
The problem with this is the user sees the view change back to VC1 then changes to VC3 due to the "pop" and then segue.
If I omit the navigationController?.popViewController(animated: true) and go directly to VC3 it works as expected except when the user uses the back button from VC3 where it returns them to VC2 which is the form they filled out but I really want them to skip VC2 and go back to VC1.
Well you have two obvious choices, both very easy.
Either go ahead and push from VC2 to VC3 and then remove VC2 from the stack, by calling setViewControllers(_:animated:) with [VC1,VC3], or else...
Change what happens when the user pops from VC3 so that we pop all the way down to VC1, by calling popToRootViewController(animated:).
I have a CoreData project where:
-VC1 has a table of items. Clicking a cell invokes didSelectRowAtIndexPath func which leads to VC2 with presentViewController method.
-VC2 shows detail of the selected item. There is a button Edit which leads to VC3 where I can edit the details of the item and save, or another button to go back to VC1.
-From VC3 to VC2: When I edit the detail and save in VC3, VC3 will be dismissed, VC2 will reappear and the updated information is shown. No problem.
-From VC2 to VC1: When I press back button in VC2, VC2 will be dismissed, and VC1 is shown but the table Data are original ones and the updated detail/item is not shown. It will be shown only if I quit the app and rerun it.
I tested with print() to see if VC1's viewDidAppear(where I have the standard fetchAndResults and tableView.reloadData()) will kick in when returning back from VC2, and I noticed it doesn't print.
Does it mean VC1 is not disappeared when VC2 is presented with didSelectRowAtIndexPath func?
If so, how do I make VC1 to rerun its viewdidappear?
I tried to reload VC1's tableview from VC2 just before dismiss, but it gives me unexpected nil error.
Help me! Thanks.
I've got a hierarchy of 3 ViewControllers on a UINavigationController app.
Start in VC1, from there you can load VC2. In VC2 you can load VC3.
You can navigate backwards through the VC's by pressing the left nav button on the navbar.
But the designer wants to be able to jump from VC1->VC3, and then if you press the left navbar button to go back it will take you to vc2.
Is it possible to have have this kind of navigation with a NAV controller?
If the user wants to go VC1-VC3 can i push both VC2 and then VC3 onto the navigationController stack so that the navigation is maintained correctly.
Also if the user wants to go from VC3->VC1 can i pop both VC3 and then VC2 off the navigationController stack so that VC1 displays?
First - tell your designers that this kind of navigation is confusing for the users and they should take some more usability and UX classes. Second - yes it's possible - the easiest way would be to call
[navigationController setViewControllers:newViewControllers animated:YES];
This will replace the entire navigation stack, so ensure that it contains [VC1, VC2, VC3] (and whatever else might happen to be before them)
The normal back button will pop to the previous view controller. You could make a left bar button in you V3 which will pop to a given view controller in your hierarchy using the UINavigationController method (giving your V1 instance as viewController)
- (NSArray *)popToViewController:(UIViewController *)viewController animated:(BOOL)animated
Push BOTH VC2 and VC3 onto the stack to preserve the navigation when pressing the back button. To go from VC3 to VC1 you can use...
[navigationController popToViewController:vc1 animated:YES];
or if VC1 is the root...
[navigationController popToRootViewControllerAnimated:YES];
I have the base ViewController which i my main menu(VC1).
From there I navigate to another VC which displays a UITable(VC2). From here i can call
[self.parentViewController dismissModalViewControllerAnimated:YES];
To move back to the main menu. That works fine.
If i load another VC(V3) with displays a UIWebView from VC2 and want to jump back to the main menu(VC1), how can this be done in the best way?
So I navigate VC1->VC2->VC3 and then want to jump VC3->VC1.
My app doesn't have a UINavigationViewController or anything like that.
Many Thanks,
-Code
You could try creating a method in the parent vc (vc2) that you call from vc3 that does the following:
-(void)dismissTwo
{
[self dismissModalViewControllerAnimated:NO];
[self.parentViewController dismissModalViewControllerAnimated:YES];
}
That's untested, but give it a shot.
Its tricky if you used navigation controller you could have popped to root view controller using poptorootviewcontroller.
However in your case if you can implement a delegates for VC2 and VC3. In the delegate for VC3 in VC2 dismiss VC3 and call delegate of VC2 which is implemented in VC1.
So basically the flow is as follows
Create VC1
When you create VC2 from VC1 assign delegate to VC1
When you create VC3 from VC2 assign delegate to VC2
From this point on you can pass messages in a cleaner way between the view controllers.
For sake of simplicity I have 3 UIViewControllers named, vc0, vc1, vc2. My Flow of operations is a button in vc0 calls
[vc0 presentModalViewController:vc1]
Then in vc1 I have another button in vc1 that calls
[vc1 presentModalViewController:vc2]
In both vc1 and vc2 I have an X button that calls
[self dismissModalViewController];
Now the first run threw that flow is fine, vc1 is presented modally, followed by vc2 after the correct button presses. Dismissing the views also behaves correctly. However, when I attempt to start the flow all over again I'm unable to present vc2 modally from vc1. Has anyone else run into a similar problem before?
I think You might be missing the allot + init for the view controllers that you want to present