Consider this modal stack
A <-> B <-> C
\--------/\
A can present B or C.
Whenever I need to leave C I need to end up on B,
which means if I got to C from view controller B I can just dismiss.
If I got to C directly from A then I need to unwind back to A and present B.
Bonus points if the latter case can be animated as C -> B transition bypassing the show of controller A.
Related
I am building an app with 6 ViewController (lets call them A, B, C, D, E and F). A is the "Menu" ViewController.
From A you can reach B or F.
From B you can go back to A or go on to C.
From C you can go back to B or go on to D.
From D you can go back to C or go on to E.
From E you can NOT go back to D, but you can go back to A or to B.
From F you can only go back to A.
My question is: Which segues should be 'show' segues and which segues should be 'unwind' segues? Or is there maybe another thing I should do?
Show - forward
unwind - backward
So for e.g. -
when moving from A -> B
use show
now when coming back i.e. B -> A
use unwind.
If you use "show" segue then you will use unwind to go back to any ViewController that has come before it in the view hierarchy but if you use "present modally" then you have to use dismiss to get back. Though with unwind you can go from the latest ViewController to the first most ViewController but with dismiss only the latest ViewController gets dismissed. And you can have as many unwinds as you want as long as you create an #IBAction for each and provide identifier.
I have a simple app with two ViewControllers. View controller A presents B programmatically (by instantiating it and calling present). Then B, depending on user input, may perform an unwindSegue to A (which works fine) or present another instance of B (again programmatically via present). This can be repeated in a arbitrarily long walk of B view controllers.
The problem is that whenever more than one B instance was shown, the unwind segue works, A comes in with the custom animation I set up for it but then the previous B appears.
A -> B -> (unwind) -> A -- Works fine
A -> B_1 -> B_2 -> ... -> B_N -> (unwind) -> A appears but then B_(N-1) shows.
I tried dismissing B_i when I present B_(i+1), but then all B's are dismissed and I end up in A.
I hope my explanation isn't too convoluted!
I don't know if it makes any difference, but B is a TableViewController and A is a regular ViewController.
I am an experienced iOS developer, but I've stumbled upon an issue that I'm not entirely sure how to solve.
Lets say for example I have 3 UIViewControllers, A, B, and C respectively. A is the root and B is presented on top of A and C is presented on top of B.
B and C are presented using presentViewController:animated:completion:
So the presentation stack looks like this.
[A] -> [B] -> [C]
In my program, I want to dismiss B and only B. The docs for
dismissViewControllerAnimated:completion: says that if I dismiss B, it will ask its A to dismiss B and then will also dismiss C as well. I do not want that. I want to dismiss B only such that A will choose C as its presentedViewController like so
[A] -> [C]
Is this possible?
--------Notes-------
I realize that this seems more suited for another presentation pattern where A,B,C would be siblings under a common parentViewController. But I May not use that.
The presentedViewController/presentingViewController pattern is just like a doublylinked list. However, since these properties are read-only, I can not do any node manipulation.
Could you use a navigation controller with the navigation bar hidden and push the controllers rather than present them (using a push and pop animation that mimics that of presentation).
Then use setViewControllers to replace the ABC stack with an AC stack?
I'm working in iOS 7.1~ with several UIViewControllers in Interface Builder storyboard.
One thing I noticed was how much lag and delay there is when my program performs segues from the top UIViewController (let's called A) to the others (B, C, and D), and, given that I would like to support segues between B, C, and D without passing back to A, I wonder if it makes sense to preload all A, B, C, and D, and then reuse them when the user either goes back or between B, C, and D.
The question is how can I do this? I am already keeping/saving pointers to each UIViewController in the others once it is created, but when prepareForSegue:(UIStoryboardSegue*) is called automatically, the destinationViewController always appears to have a new address, different from the one I saved in my pointer. I would think that using this provided destination view controller is the same as loading a new one from scratch.
Let's say A has pointers to B, C, and D. Is there some way to declare B, C, and D, allocate them very early, and then keep reusing the B, C, and D as the user is moving between them? I thought about and tried giving A some delegate methods that B, C, and D would have A call upon rewinding, but I got error messages telling me A was in the middle of presenting and could not perform the segue to C or D. So it seems safest to go straight from B to C or D without passing through A. It still leaves the problem though that relying on prepareForSegue from B seems to give me a new destination controller C or D, and not the one I had saved in A (or B).
Thanks in advance for your help.
I have three view controllers A, B and C.
C is the target.
From A, I have a segue named showCFromA to view controller C.
From B, I have another segue named showCFromB to view controller C.
Now, when C is displayed (shown from B), I tap on the "Back" button, but at this stage, it shows A, and not B as I expected.
How can I fix that?
Don't mess with Back - it makes for a disjointed app experience. You end up at a place you don't expect to be and navigation just doesn't feel right.
If you have a B on the stack, you can just
popToViewController:animated:
to return to the specific view controller (B) that you want to see.
If you have gone from A directly to C with no intervening stop at B, you can't go there with back. Instead you should just push a B.
If your B should be on the stack - i.e. you went from B to C - then B is where you should end up if you simply go back. If that is currently not the case you need to post some more details to help diagnose the problem.
What is confusing right now is what you actually have on the stack. You mention being at A and going to C, then being at B and going to C, but the order in which you do this (and if these are two separate cases) affects the outcome.
After checking the source again, I found the issue is not properly handling navigation vc stack. When push new VC from B, when viewWillDisapper is called (B), I added "popViewController". Therefore, navigation view controller array has count of 2 (the middle element is removed). This makes strange behavior: From view controller C, I cannot go back.