Unwind Segue - Where to Drag Exit? - ios

I am trying to understand how the unwind segue works. First I created 3 ViewControllers.
GlobalVC
-LoginVC
-RegisterVC
I set the initial page the GlobalVC (only authenticated user can see). I set a segue from:
GlobalVC to LoginVC called globalToLogin and LoginVC to RegisterVC called loginToRegister. Here is my storyboard:
For the registerToLogin direction, I used this work-around (in RegisterVC), but looks a bit ugly.
#IBAction func unwindToLogin(sender: AnyObject) {
//Dismiss View
dismissViewControllerAnimated(true, completion: nil)
}
However, now I am trying to direct from LoginToGlobal
First, I selected Login button, dragged it to LoginVC:
#IBAction func loginButton(segue: UIStoryboardSegue) {
performSegueWithIdentifier("unwindToGlobal", sender: self)
}
After setting segue: UIStoryboardSegue, now it gets available to right-click on Exit. But, I got confused here. Whatever I tried to drag the circle inside Exit to, it gives an error:
Terminating app due to uncaught exception 'NSInvalidArgumentException', >reason: 'Receiver (0x7fdd2068a480>) has no segue with identifier 'unwindToGlobal''
Where should I drag the circle on? ( I keep seeing Unwind segue to 'Exit' )

The unwind action method is defined in the destination view controller (e.g. in GlobalVC).
#IBAction func unwindToGlobal(segue: UIStoryboardSegue) {
// this may be blank
}
And then, when you're hooking up the button to this action, you don't drag to the code sample, but rather to the "exit outlet" icon above the scene:
See this answer for more screen snapshots.

Related

What's wrong with my segue code in Swift?

I'm trying to segue into a 'settings' View Controller by clicking a button, and I'm assembling it via code but don't know what I'm doing wrong.
This is my button code:
#IBAction func settingsButton(_ sender: UIButton) {
self.performSegue(withIdentifier: "SettingsViewController", sender: self)
}
The View Controller is called 'Settings View Controller' (unsurprisingly). The app crashes whenever I press on it in my Simulator.
It'll probably be a simple thing, but any ideas what I'm doing wrong?
You must set your segue identifier whatever you want (for your question = SettingsViewController) from storyboard :
Hope it helps...

Go back to previous page using unwind segue

I wanted to just go back to my previous page
from Attendance in going to Leave and Leave back to Attendance
LeaveViewController.swift
#IBAction func LeaveAttendanceSequeConnect(_ sender: Any) {
performSegue(withIdentifier: "LeaveAttendanceSegue", sender: nil)
}
Attendance.swift
#IBAction func LeaveUnwindSeque(segue: UIStoryboardSegue){
}
and then on my Leave Scene
I have ctrl drag to Exit
Pressing the Back button in Leave wont go back to Attendance
The segue should work without needing another segue to leave the unwind. Try this:
1) Keep your original LeaveAttendanceSequeConnect (which should have been bound with ctrl drag from your view controller in story board over to your corresponding .swift file).
2)Get rid of the LeaveUnwindSeque code and unbind that rewind segue properly by deleting the segue (p.s. is segue with a "g" not seque). Now click on the segue connection of the LeaveAttendanceSequeConnect in the storyboard. Make sure the original navigation controller has attributes and looks the same on the storyboard like figures A) and then make sure your second segue has attributes/storyboard like figure B).
A attribute:
B attribute:
B storyboard:
A: storyboard:
The signature of the unwind is incorrect.
#IBAction func LeaveUnwindSeque(segue: UIStoryboardSegue){
}
replace with
#IBAction func LeaveUnwindSeque(_ segue: UIStoryboardSegue){
}

Swift 3: PerformSegue WithIdentifier Not Displaying View Controller, No Errors

When I execute the line below, my destination view controller is not visually presented but there are no errors in the log:
performSegue (withIdentifier: "DetailsViewController", sender: self)
Let's step back from a problem. Imagine my successful setup: ViewController is loaded and upon some user action the above line would actually open a new DetailsViewController. I tested - everything works as expected - so I know it works.
But the problem presenting DetailsViewController begins when I decide to implement some third party framework by adding a CamViewController to my ViewController and perform segue upon element tap inside CamViewController, then delegate method passing this action back to ViewController from which I would open DetailsViewController. With this architecture setup I get no errors in a log but visually nothing is opening. No DetailsViewController ever presented.
A bit more details of architecture:
ViewController presents CamViewController with line self.present(camViewController, animated: true, completion: nil)
CamViewController implements a protocol to call some method on user action
ViewController conforms to CamViewController protocol and delegate method successfully runs on user action (log shows it is working)
Calling DetailsViewController with segue identifier is executed successfully performSegue (withIdentifier: "DetailsViewController", sender: self) but DetailsViewController is never displayed on screen.
This method below prints prepare for segue Optional("DetailsViewController") which sounds correct.
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
print("prepare for segue \(segue.identifier)")
}
I also tried adding super.performSegue - no luck
First I would change your segue code to something more like this.
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if (segue.identifier == "DetailsViewController"){
print("prepare for segue DetailsViewController")
} else {
print("prepare for segue other")
}
}

Swift back button segue

I have a navigation tableview controller Calculator and that goes to AddActiveIngredients which is where I add everything in for the calculator.
I have the segue method backButton in Calculator and in AddActiveIngredients I have click dragged the segue from the controller to exit and selected the segue in the Calculator class.
The segue identifier is also backButton but it's not doing anything.
I've tried this code to try and trigger the segue manually but that's not working. Am I missing something so simple?
override func didMoveToParentViewController(parent: UIViewController?) {
if (!(parent?.isEqual(self.parentViewController) ?? false)) {
print("Back Button Pressed!")
self.performSegueWithIdentifier("backButton", sender: self)
}
}
It sounds like you just want to remove the AddActiveIngredients from the stack. If so, you just need to call a function to dismiss it.
func dismissVC() {
dismissViewControllerAnimated(true, completion: nil)
}
You can put that in a button tap or something else. It'll work with Show and Modal segues. Unwinding may be overkill for what you're doing.
Hope it helps!
To use the Exit icon you need not create a segue at all.
All you have to do is add a method in the ViewController to which you want to unwind to and add a method with the signature:
#IBAction func myUnwindAction(segue: UIStoryboardSegue) {
// do stuff
}
Remember, you have to add this method in the target ViewController
When you Control-Drag from a button to the Exit icon, this method will now show up.
When you now click the button, the current ViewController will be popped and the action method in the target will be called.
Hope this helps.
with Swift 5 you can use Dismiss function
#IBAction func dismissViewController(_ sender: Any) {
//Go back to previous controller
dismiss(animated: true, completion: nil)
}

Unwind segue doesn't work SWIFT

I have a navigation controller, with a table view. When I press a cell, the detail view controller opens.
In my root view controller I have :
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "detailview" {
var destination:DetailViewController = segue.destinationViewController as DetailViewController
destination.delegate=self
}
}
In my detail view controller I have a back button :
#IBAction func back() {
self.navigationController?.popViewControllerAnimated(true)
}
The issue is, after 2 go to and return, my app crashes when I go back on the root view controller pressing back button. The console doesn't give me errors. It just crashes.
I think I have forgotten to unwind the segue.
So in my detail view controller I added :
#IBAction func unwindToViewController(segue: UIStoryboardSegue) {
println("unwind function")
}
I connect this function to my back button with "exit" in my storyboard.
When I run my app, If I press on the back button, the console doesn't display my print "unwind function", so unwindToViewController isn't called. Why ?
And my app still crashes...
Your unwindToViewController method should be placed in your root viewController, then ctrl-drag from the button in the detailViewController to the Exit icon in InterfaceBuilder. Choose that method in the popup menu.
Another approach would be to declare a protocol with a function in the rootViewController that is called from the detailViewController. You already set the rootViewController as the delegate of the detailViewController. Within that function you call dismissViewController.
Swift answer...
I had a similar problem.
The func: "segueForUnwindingToViewController(toViewController: UIViewController, fromViewController: UIViewController, identifier: String?) -> UIStoryboardSegue" was never called.
Solution:
since I didn't have a "UINavigationController", because I simply embeded the app in a Navigation Controller, I created a UINavigationController subclass for the Navigation Controller and added the function named above on it. Now the app calls "segueForUnwindingToViewController"

Resources