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.
Related
I want to detect if back button is pressed in the next viewController in a navigationController.
Let's say I have VC_A and VC_B viewControllers in a navigationController. I know how to detect if back button is pressed in a current view controller but I do not know how to detect it in a previous viewController.
Edit:
I go from VC_A to VC_B and when I press back button in VC_B then I want to call a function in VC_A.
You could use notification center. This link has a nice tutorial: https://learnappmaking.com/notification-center-how-to-swift/
I want to detect if back button is pressed in the next viewController in a navigationController.
I'm not sure I understand this exactly, but it really doesn't matter much: in essence, you're talking about some view controller (call it controllerA), whose views aren't currently visible, finding out about a change that affects some other view controller (controllerB). The usual reason for needing such a thing is so that controllerA can update some data that it manages.
A better way to handle that is to have both controllers share a common data model. Any application state that's affected by something like a view controller being dismissed is shared data that should be part of the data model. controllerA really shouldn't care about whether controllerB's back button was tapped or not... that event is only the business of controllerB (and arguably the navigation controller that manages it). What controllerA should care about is updating its own views according to whatever changes happened while it was off screen, and those changes should be recorded in the model by controllerB and any other view controllers that might have been active along the way.
I'm suggesting you to do that with Notification Center like AglaiaZ suggested you. But if you're not feeling comfortable with using Notification Center, then try this more basic solution with viewWillAppear delegate method in viewController from which you're tracking are you back from B VC. So, let's go.
Set this variable in your current view controller class where you want to trigger method when the back button is pressed on the specific view controller, let's call that specific view controller B VC.
let isFromBViewController = false
Then in code block where you're triggering the transition to B VC set this variable to true.
func goToBViewController() { // This method is triggering transition from A VC to B VC
isFromBViewController = true }
And then in viewWillAppear delegate method check did current VC from which we triggered the transition to B VC have appeard from B VC.
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
if isFromBViewController {
// code for doing something when you got back from B VC
isFromBViewController = false
}}
And that's it.
But, again I'm suggesting you to use the notification center as #AglaiaZ suggested, the tutorial is easy, and with that tutorial I've also learned how to use Notification Center and how to create and use custom notifications.
Good luck.
If I understood correctly, you want to do something when the back button in the navigation bar at the current view controller is pressed, and the user is going back from the current B view controller to A view controller.
Put this line of code in the view controller in which you want to track when the user has pressed the back button.
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
if isMovingToParent {
//your code when back button is pressed
}
}
I'm trying to get an unwind segue working (in Swift) and have read through all the "unwind segue not working" posts I could find but haven't yet found whatever it is I'm doing wrong. So.
I have a UISplitViewController with a UITableViewController as my left-hand menu and two UINavigationController+UITableViewController detail views that I'm switching between. Segue-based navigation from my left-hand menu works fine. It's when I want to programmatically unwind that things do not.
I've created an #IBAction function in my first view controller, the one I want to unwind to, like this:
#IBAction func unwindToDocuments(_ segue: UIStoryboardSegue) {
}
(My first view controller is my "Documents" view.)
Then, in the second view controller, I connect an unwind segue to the exit node with identifier unwindSegueToDocuments and action unwindToDocumentsWithSegue:.
It's my understanding that should be all I need to do. However, when I try:
self.performSegue(withIdentifier: "unwindSegueToDocuments", sender: self)
it doesn't do anything. It stays in my second view controller as the detail view.
I'm using self.performSegue there because I'm in a closure. It's some network work so it's being done in a DispatchQueue.async() background queue. However, the performSegue call is in a nested DispatchQueue.main.async() block at the end. (Or, rather, I've tried it both/all ways, and still can't get it to unwind.)
Nothing helpful appears in the console.
I am trying to create an unwind segue that takes me back two viewControllers, and I thought I had everything set up correctly, but it crashes with no error printed when I perform the segue...
Here's what I've done:
In the DESTINATION viewController, we'll call it VC1 (bottom of the stack) I created this action:
#IBAction func unwind(segue:UIStoryboardSegue){}
In the interface builder I hooked up VC3 (the third view controller up) to the unwind segue via the exit button and named it "unwind".
I call perform for segue like so:
performSegue(withIdentifier: "unwind", sender: self)
Here is the view controllers and segue identifier
http://imgur.com/a/gJPYQ
The "Delete Trip" button calls the segue AFTER all the other logic has been taken care of.
As soon as that is called, my app crashes with no error message and shows me the AppDelegate screen. What's going on?
If you pushed your VC, you could use:
navigationController?.popToRootViewControllerAnimated(true)
If you have two VC's presented modally, then you will need to dismiss two VC's modally. Use:
dismiss(..., completion: {
dismiss(..., completion: nil)
Your current "unwind" segue is simply presenting the original one again..and maybe you don't have identifiers set up correctly or you are overlooking your view hierarchy.
I created a segue between two controllers(A, B). In controller A, I am using "performSegueWithIdentifier" method to show controller B's view. However, I want to add an animation on presenting the B. I want it to show/hide from the bottom of the screen. How should I do this?
I achieved this using Present As Popover when choosing the kind of segue in Attributes Inspector. Make sure you point your anchor to the view controller you are segueing from, this answer was pretty helpful.
Make sure you give it an identifier (using this identifier below) and use the typical perform segue code whenever you wish to perform the segue:
dispatch_async(dispatch_get_main_queue()) {
[unowned self] in
self.performSegueWithIdentifier("Identifier", sender: self)
}
Make sure you replace "Identifier" string with a string of your own segue identifier.
I have an app with a UIViewController that I am using to add an item to a UITableView. The user fills out a few fields, and then the data displays in the cells. I'm doing an unwind and using a function on the calling view, to retrieve the data. To create the unwind, I click dragged from the controller to Exit, and selected my function.
Now, I want to also use the same UIViewController from a different UIViewController, to permit users to edit the data that was added. When I click the accept button, it is unwinding to the UITableViewController, instead of to the view from which it was called for editing.
The code for the accept button is:
#IBAction func acceptButtonClick(sender: UIBarButtonItem) {
performSegueWithIdentifier("ReturnFromAddItem", sender: title)
}
What I want to do is this:
#IBAction func acceptButtonClick(sender: UIBarButtonItem) {
if !editingFields {
performSegueWithIdentifier("ReturnFromAddItem", sender: title)
}
else {
performSegueWithIdentifier("ReturnFromEditItem", sender: title)
}
}
It doesn't appear that I can do this though. My segue ID is ReturnFromAddItem. I don't see a way to add two unwind segues. Any idea how I might approach this? I want the same functionality that I have on the add. I want it to unwind a function on the caller.
I should elaborate a bit. I was able to add the second unwind with control click drag to Exit, but when I call it in the performSegueWithIdentifier, it does nothing. There is no error, but it does not leave the view controller and go back to the caller.
Editing to elaborate further.
The base controller is called BaseViewController. This is a UITableView. In the navigation bar is a "+" button that calls a UIViewController named AddViewController. When the "+ button is clicked, there's a segue that takes the user to AddViewController. The user fills out a few fields and clicks an Accept button. The code for the Accept button is listed above. It calls the unwind segue, and we go back to BaseViewController. When the user taps on an item in BaseViewController, it takes the user to a UIViewController named InformationController. From there, I'd like to give the user the chance to edit the data by clicking on a Settings button on the navigation bar of InformationController. This would segue to the AddViewController UIViewController, but it would use it to edit existing fields. I want to unwind and go back to InformationController when AddViewController is called from InformationController, and back to BaseViewController when AddViewController is called from BaseViewController. The problem I'm having is that even though I added an unwind segue for AddViewController to InformationController, nothing happens when I click the Accept button.
Final Edit:
I think that I have it figured out. In InformationController, I am using viewWillDisappear to call the unwind segue back to BaseController. When I click settings to call AddViewController from InformationController, viewWillDisappear is firing, and I am unwinding to BaseViewController. So what I need to figure out is whether I should continue to use viewWillDisappear and find a way to tell it that it is not disappearing because I'm done with it, or if I should be executing the unwind from somewhere else.