I've looked up examples on how to reverse segue in xcode and swift with a storyboard but I can't find an example that pertains to this specific situation where I segue into a navigation controller beforehand. Any pointers?
If you use navigation controller, you can use
self.navigationcontroller?.popviewcontroller(animation: true)
Please try this
It is the same as an ordinary unwind segue.
In your source view controller add this action
#IBAction func unwindToMain(segue: UIStoryboardSegue) {}
And from your destination view (which is titled Action) connect your button to the Exit.
Hope this helps :)
Related
I am trying to use an unwind segue to logout from my app.
Here is my view hierarchy:
MainVC->(show)->ConnectionVC->(show)->HomeTabBarVC->SettingsVC (4th tab of the HomeTabBarVC containing a tableview)
MainVC, ConnectionVC and HomeTabBarVC are in three different Storyboards.
When pressing the "Disconnect" row of SettingsVC, I want to unwind to MainVC.
I already tried to follow this:
What are unwind segues and how do you use them?
and
Unwind segue and nav button items not triggering after tab bar controller added
The unwindToThisViewController function (which I put in MainVC) from the tutorial is triggered but the only thing that happens is going back to the first tab of HomeTabBarVC.
I tried to execute this action in SettingsVC in two ways:
(self.tabBarController! as! HomeTabBarVC).performSegue(withIdentifier: "unwindToMainVC", sender: self)
and
self.performSegue(withIdentifier: "unwindToMainVC", sender: self)
Neither are working...
Any toughts?
You can do this without using unwind segues. Just use popToRootViewController:
navigationController?.popToRootViewController(animated: true)
I found a solution : after seeing that I had the "Presenting view controllers on detached view controllers is discouraged " warning, I created a Delegate to execute the segue in my HomeTabBarVC and it works fine! Thanks everyone for your help!!
I am use to performing unwinds to the easy what that is like this:
First set this on the destination view controller:
#IBAction func unwindToThisViewController(segue: UIStoryboardSegue) {}
Finally drag and drop and then pick the wanted unwind:
But till Xcode updates to 8.2.1 if you have the destination view controller with some extensions it doesn't appear on the list (Manual Segue). I didn't update to 8.3 because I'm still using Swift 2.3 so I don't know in further versions this bug is solved.
Instead of having to move all the extensions in the same file, which it will be a chaos find anything there. I am wondering if there is any other way to perform this action without using the storyboard step.
I am currently using navigation controller, maybe popToViewController will do it? I don't know honestly.
Thank you very much for the help.
In the storyboard, give your unwind segue an identifier.
Then, in your code do:
performSegue(withIdentifier: "SegueID", sender: nil)
Source: https://spin.atomicobject.com/2014/12/01/program-ios-unwind-segue/
My app's navigation flow looks a bit like this:
UINavigationController - MasterViewController > DetailViewController > InfoViewController
MasterViewController contains the following method:
#IBAction func unwindToMaster(with segue: UIStoryboardSegue) {}
In DetailViewController, there is a similar method:
#IBAction func unwindToDetail(with segue: UIStoryboardSegue) {}
I use these methods, along with UIButtons, to allow the user to advance forward and back through the navigation hierarchy. In interface builder, I see the method under DetailViewController when I right click on "Exit" in InfoViewController, but when I right click on "Exit" in DetailViewController, no other unwind segues are listed.
I have consulted multiple online sources (Ray Wenderlich, relevant StackOverflow questions) instructing the correct way to produce unwind segues in interface builder, but none of these have helped solve the issue. Right now, I need help figuring out what the problem is in the first place. As development usually goes, it's probably something staring me square in the face.
I am running Xcode 8.1 using Swift 3. Thank you.
To re-iterate: not only an Action for a Storyboard Unwind Segue has to be placed in the same source file as class definition for an unwind-to (destination) View Controller (e.g., #IBAction func prepareForUnwind(segue: UIStoryboardSegue), detected as prepareForUnwind[With]Segue in a "Presenting Segues" list), but also that View Controller cannot have ANY extensions in ANY secondary source files. You have to merge class definition and all extensions into a single source file.
(As of Xcode 8.2.1.)
In my case, I had a complicated inheritance in my view controller and it was a reason why Interface Builder did not see my unwind. So this workaround works for me well:
Go to YouCollViewController.swift file and delete all classes, protocols, generics, etc. your view controller implements in view controller's declaration
Inherit your view controller from UIViewController
Go to the storyboard and connect your action with the unwind, it should appear in unwinds list
Go back to YouCollViewController.swift file and discard all the changes
I consulted Apple's Developer Library (specifically the page "Using Unwind Segues"). There, the example definition of an unwind action is:
#IBAction func unwindToMainMenu(sender: UIStoryboardSegue) {
let sourceViewController = sender.sourceViewController
// Pull any data from the view controller which initiated the unwind segue.
}
Applying this example in my code, I changed my unwind action declarations to:
#IBAction func unwindToMaster(sender: UIStoryboardSegue) {
print("Unwinded to master.")
}
and
#IBAction func unwindToDetail(sender: UIStoryboardSegue) {
print("Unwinded to detail.")
}
I also made sure that each method was contained within the same file as MasterViewController's class declaration. After further testing, I found that all extensions of MasterViewController had to exist in the same file for interface builder to find and recognize the unwind segue.
Now, in storyboard, the exit menu shows both unwind segues. My conclusion is that by fiddling around with where the methods are placed and how they are declared, a configuration that interface builder can recognize will be found. I hope it will be less touchy in the future, as my current method organization is very long and difficult to navigate.
Because none of these answers helped me and I didn't want to mess around with my code that much. Here another solution you can give a try.
Starting from the point where you have already added the unwind function to your MasterViewController.
First I have gone ahead and added a new ViewController to my storyboard as well as a new Cocoa Touch Class File of type UIViewController and connected it with my Storyboard one (I called it the HelperViewController).
Then you can add the same unwind function, you already have inside your MasterVC to your newly created HelperVC.
#IBAction func unwindToMaster(with segue: UIStoryboardSegue) {}
Now connect the Helper to your DetailVC. Your Storyboard should look somewhat like mine. You should get the same option as me if you ctrl + drag and drop to the exit of your DetailVC. When the connection has been established and you hover over the newly created segue both the Master and the HelperVC should be highlighted. Now you can delete the HelperVC again and everything should work as expected.
I hope that helped!
With swift 4 XCode 9.2 I found that you need to drag the reference from the yellow icon at the top of the viewController to the "Exit" reference of the target viewController in the left details panel. Hope this helps!
Sometimes XCode restart makes the actions appear.
I have a view controller, after a button is pressed I want it to unwind to the original table view controller and then let it segue into another view controller.
I don't segue directly to the new view controller because I want that when the back button gets pressed it returns to the original table view controller.
But when I do this it loads the view controller where it's supposed to end, but directly after that it directly returns to the original table view controller
This is my setup in storyboard:
http://imgur.com/dcvvxi5
And this is the code I use to make it happen.
I call this code in the view controller where the button gets pressed:
self.performSegueWithIdentifier("unwindChooseHome", sender: nil)
And this code inside the original table view controller:
#IBAction func unwindChooseHome(segue: UIStoryboardSegue) {
self.performSegueWithIdentifier("destination", sender: nil)
}
Hopefully you understand my question I am not native. I don't really know what I am doing wrong maybe there's a totally different way to make this happen.
Thanks in advance :)
I imagine that the problem is that you're triggering the "destination" segue prior to the completion of the unwind segue.
Instead of triggering the "destination" segue immediately inside of the unwind action method, try setting a flag on the original view controller that you can then check in viewDidAppear: and trigger the segue at that point.
I have a UIViewController which has a button that performs a modal segue to a UIViewController as a Form Sheet. On that form sheet is a cancel button with an unwind segue back to the original UIViewController. This seems to work perfectly happily and dismisses the form sheet.
As soon as I select the original UIViewController and select the option in XCode to Embed in a Navigation Controller, the unwind segue no longer seems to work and the modal form sheet will no longer cancel.
I'm sure there is a simple explanation, but it is currently evading me, so any thoughts welcomed.
Thanks.
I don't know why you get the behavior you're seeing, I see it too. It happens for both the page sheet and form sheet presentations, but not for full screen. However, the unwind segue is still calling the method you put in the original controller (the one you connected the unwind segue to). So, all you need to do is put a line in that method:
[self dismissViewControllerAnimated:YES completion:nil];
This is already answered, but the above did not give me the full solution, so i thought i would share mine.
For me the unwind method was never called, so i could not do what was described above. Instead i made a simple button with an IBAction and called it. Swift example below:
#IBAction func cancelToRecipeController() {
self.dismissViewControllerAnimated(true, completion: nil)
print("cancel to recipe controller ran")
}
Thanks to #rdelmar above for the method call!
(This was added for ios 9)
self.dismissViewControllerAnimated(true, completion: nil)
"dismiss" didn't work for me but popToRoot works well.
[self.navigationController popToRootViewControllerAnimated:YES];