I have 3 ViewControllers which segue operations is prepared more or less like this:
A --editview-> B ---showEdited->C
Where A is for list of objects B is for edit certain object and C is for showing edited object. At this moment when user is getting into C and trying to go back he is landing in edit state B instead of a list.
Is it possible to close segue while performing to the new one? so that user will be back from C to A?
I don't know if I understand correctly what you want to do but I hope this will work.
if let firstVC = self.navigationController?.viewControllers[0] {
self.navigationController?.popToViewController(firstVC, animated: true)
}
Have you tried looking into unwind segues. Unwind segues help when you have a sequence of VCs, say 1 -> 2 -> 3, and an unwind segue takes you from 3 directly back to 1.
Try these links:
https://spin.atomicobject.com/2014/10/25/ios-unwind-segues/
What are Unwind segues for and how do you use them?
Hope this helped.
Related
I currently am learning how to program in Swift and have made 3 different pages; Pages A, B, and C. From page A, I am able to navigate to page B, and from page B, I am able to go to either page C or page A. When I go to page C I can go back to page B or page A.
The issue that I am running into however is that if I go from Page A to Page B to Page C back to Page B, when I try to close Page B, it would display Page C briefly before closing back to page A.
All of these are on separate viewcontrollers and I've just been presenting all of them modally each time
I've tried using Unwind Segues Step-by-Step and Create Unwind Segues in Swift 3
to understand what I've been doing wrong, however from what I've read on them (and from my limited knowledge of Swift), none of them discuss going back a single page and then trying to close after. They all go from 1 -> 2 -> 3 back to 1 without the intermediate step of going back to page 2.
#IBAction func close (_ unwindSegue: UIStoryboardSegue){} is what I've been using as my unwindSegues linking these up to my Exit placeholder. This was done on both Pages B and C
Currently there is no error message, it appears to work but it does show that intermediate screen which is not what I am looking for.
Thanks!
You said:
when I tap on the back button on page C -> B it shows that I trigger an Action that presents Modally (if that helps)
That is precisely the problem. Having gone from A to B to C, C should not then modally present B again. You’re creating a new, second instance of B. You’d have a view controller hierarchy that looks like:
A » B1 » C » B2
If, though, you successfully dismissed/unwound from C to B, you would have ended up with only A and B in the view controller hierarchy:
A » B
And then, when B went to dismiss/unwind to A, C would be long gone and there’s no way you’d see it in your animation.
If you’re using unwind segues, I’d suggest that view controller A had an unwind action like so:
#IBAction func unwindToA(_ segue: UIStoryboardSegue) { }
And view controller B could have an unwind action like so:
#IBAction func unwindToB(_ segue: UIStoryboardSegue) { }
Now, when C wants to unwind back to B, if you could use the latter unwind action. If you want to unwind to A (either from B or C), you could use the former one.
Just make sure that you never present/show when you want to go backwards in the view controller hierarchy. Either use unwind segues, or dismiss/pop as appropriate.
I don't really understand your question. But I guess your problem is you used present instead of dismiss when you back to B from C.
Sorry, your question is not fully clear to me . So far I understand if you wanna back from C to B View Controller , then you can do it Simply use
self.dismiss(animated: false, completion: nil)
in Your Exit Button action . Hopefully it will help .
Seems quite confusing question description.
Not sure but maybe you have mistakenly added segue from Page B -> C on the same Back button. Please check that also.
I've created SimpleUnwindExample project on GitHub. Hope It will help in to fix your issue.
Repository Link: https://github.com/harshal-wani/SimpleUnwindExample
Cheers!
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'm a fresher. I used segue to go (Flow of Execution) such like that
UIViewController A => UIViewController B => UIViewController C.
And used unwind segue to move from C to A. But I am confused about how they different of each other.
And Why I use unwind segue although I have delegation.
Thank You in advance.
Regular Segue allows us to send data from one view controller to another, but it’s not easy to bring data back if the user has changed or added details in that view controller. That’s where an Unwind Segue comes in.
Read more here
Segues are for presenting a new view controller.
Unwind Segue is a special kind of segue (A go back mechanism) which moves back to the connected destination.
A->B->C->A
If you are using segue for above mentioned flow, there will be two different instance of A in the memory.
If you use unwind segue for the C->A transition
It act as a go back mechanism and it removes the C and B instance from the memory once the segue is over
There will be only 1 instance of A
If I have a storyboard that contains 3 views - a root, and two 'child' views that the root view can segue to. Is it possible for the children to segue to the other child, and then when its complete, return back to the root?
In my case, the root view may segue to view 'A' or 'B' depending on some event. However, its possible that some event in 'A' may require view 'B' to be displayed, and when its done it should return back to root. i.e., the steps of naviation would be: Root -> ChildA -> ChildB -> Root.
Currently, I have the app setup to unwind from ChildA back to root, and have it then display 'B'. Two issues arose from this method:
Unable to segue to a new view when the unwind segue is still in operation. I had to hack around this, and currently have a performSegueWithIdentifier being called with a small delay to get around it. Obviously a bad hack.
The root view controller is displayed for a moment until the new segue starts & completes.
I figured I could have A segue to B, but then when B was done, the unwind operation that I want to go back to root would have to unwind two items on the view stack??
I'm sure there has to be an obvious design choice that handles this type of thing right?
I figured I could have A segue to B, but then when B was done, the unwind operation that I want to go back to root would have to unwind two items on the view stack??
Unwind operations are not required. In your case, it might be better to have A segue to B, and when B is done, segue to root. No unwind required.
If, however, you want to stick with unwinding, Craig Phares posts how to perform multiple unwind animations without showing intermediate controllers (i.e. you would pop right back to root).
Hope this helps!
First, I believe you mean "view controller", right?
If that's the case, there are many ways you could navigate from A to B. However, it seems like you're using the NavigationController in an unusual way.
For example, is it necessary to have a segue from the root to B? If not, then maybe you should create a single segue from A to B and, when you're at B, you can use "popToRootViewController" to go back.
Or maybe you could present B modally instead of having a "show"/"push" segue to it. In that case, you would have to go back to A before going to the root.
Anyway, once you're at ViewController B, you can popToRootViewController and you'll get back to your root.
There are a lot of stuff on the net according the topic but I don't get it. I have an App with Custom segue implementation and without Navigation controller. There are cases in which I need to unwind back several steps.
For implementation I use simple calls:
CODE CUSTOM SEGUE
For wind:
[[self sourceViewController] presentModalViewController:[self destinationViewController] animated:YES];
For unwind:
[[self destinationViewController] dismissViewControllerAnimated: YES completion: nil];
As I understand when I wind segue somewhere in the memory there is data which is used during the unwind. For that reason in the custom unwind I only use read only property destinationViewController.
So how can I unwind several steps back in one action? Or I have to make several unwinds in different View controllers?
I read the following question, but I don't understand implementation.
Bellow I put example of my apps logic:
EXAMPLE
I have 4 VC which is in a chain:
VC A -> VC B -> VC C -> VC D
I wind and unwind back and forth. The logic is ok. There are situation in which I need to unwind back from VC D to VC B. How to do that? Can I unwind directly to VC B or I have to unwind to VC C and then in the unwind handler to unwind to VC B?
I also thought of additional segue from VC D to VC B, but there are remarks on the net that this is not the right way, because segue chain will get messy.
The answer to What are Unwind segues for and how do you use them? has everything you need to know about unwindSegues (I suggest you re-read it).
But for a more direct answer, yes you can unwind back from VC D to VC B. To do that you have to first implement the method in VC B:
- (IBAction)unwindToVCB:(UIStoryboardSegue *)unwindSegue
{
}
after doing so, go to the IB, and control-drag a button's action to the Exit icon, you should then pick the method you created above as the selector. (This is taken directly from the question/answer stated above).
Again, for a clearer version of what I said, read the answer of the linked question I mentioned above.
You have to use UINavigationController, just add it in storyboard as mainViewController and set 'A' ViewController as root view controller for it, then change all segues to push segue, set 'Identifires' for them, and you can use performSegueWithIdentifire to push view controller and inside view controller:
[self.navigationController popViewControllerAnimated:];
or
[self.navigationController popToViewController: animated:];
to dismiss it.