How to Perform Unwind Segue Programmatically

How to perform Unwind segue programmatically?

  1. Create a manual segue (ctrl-drag from File’s Owner to Exit),
  2. Choose it in the Left Controller Menu below green EXIT button.

Choose it in the Left Controller Menu below green EXIT button

Insert Name of Segue to unwind.

Then,- (void)performSegueWithIdentifier:(NSString *)identifier sender:(id)sender. with your segue identify.

Programmatically unwind segue

You can create unwind segue for entire view controller. To do this drag segue from view controller objet to exit object. Sample Image

After segue created it is listed in document outline.

Sample Image

Select it and give it an identifier in attributes inspector. Then inside your code when when tableview selects a cell perform this segue like any other normal segue.

override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
let title = tableView.cellForRowAtIndexPath(indexPath)?.textLabel?.text

performSegueWithIdentifier("backToViewController1", sender: title)
}

Then override prepareForSegue method to pass data to first view controller.

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if let identifier = segue.identifier where identifier == "backToViewController1",
let destination = segue.destinationViewController as? ViewController,
selectedTitle = sender as? String {
destination.selectedCountryTitle = selectedTitle
}
}

How to create Unwind segue programmatically

You can't create an actual segue without a Storyboard, but you can do the equivalent action by calling popToViewController on navigationController. Here is an example that is connected to a button to return to FirstViewController from ThirdViewController:

@IBAction func goBackToFirstVC(sender: UIButton) {
guard let controllers = navigationController?.viewControllers else { return }
let count = controllers.count
if count > 2 {
// Third from the last is the viewController we want
if let firstVC = controllers[count - 3] as? FirstViewController {
// pass back some data
firstVC.someProperty = someData
firstVC.someOtherProperty = moreData

navigationController?.popToViewController(firstVC, animated: true)
}
}
}

In an override of viewWillAppear, you can act upon that data that was passed back.

Unwind without Storyboard

You are not alone and you are not the first person to have this problem. I call this the problem of reverse routing.

To illustrate the problem, I'll show a storyboard version of a relatively complex unwind situation:

Sample Image

We have a tab bar controller with two children. The first child is a navigation controller which has pushed one view controller (the green v.c. at the end of the first row) on top of its root view controller (the yellow v.c.). The second child is a normal view controller that has presented one view controller (the white v.c. at the end of the second row).

The goal is to unwind from the white v.c. to the yellow v.c. in the top row.

If you're using a storyboard, this is trivial. The yellow v.c. contains an unwind method (the name isn't actually important), and you "hook" the exit segue from the button in the white v.c. to that method. At runtime, the user taps the button, and the runtime "magically" dismisses the white v.c., switches the tab bar controller to the first child, and pops the green v.c., leaving us in the yellow v.c. as desired.

Now do that in code! Uh, yeah, sure. How? That's the problem.

The irony is palpable. Clearly the runtime knows how to solve this problem, because it does solve the problem when you use an unwind segue in the storyboard. But there is no built-in programmatic analog when you are not using a storyboard. There is no unwind command that causes the complex unwind mechanism to become activated and do the same thing that would happen if this were a storyboard-based app.

This is a huge flaw in UIKit. Apple basically requires us to use storyboards. But everyone knows that any app developed by a team is likely to avoid storyboards, because reconciling versions of a storyboard through git is darned near impossible. So Apple doesn't seem to live in the real world; they have not provided the runtime support needed for real world development of apps.

A simple solution — simple to the point of crudeness — is just to unwind "by hand". The app has a "coordinator" object whose job is to take care of this sort of backward routing. If you are in the white v.c. and you want to "unwind" to the yellow v.c., your coordinator simply has to know that this is something we might want to do, and it knows what the necessary steps are in order to get there.

Basically, what I'm saying is that the coordinator must be supplied with a fixed list of all the backward routes the app will ever need to perform, along with instructions for how to perform them. Given where we are and where we want to go back to, the coordinator just performs the corresponding steps.

(You, the OP, will observe that I have not told you anything you don't already know. What I have outlined is, apparently, exactly your option 1. And that is correct. What I'm telling you is: option 2 would be nice, but it doesn't exist and isn't worth trying to write, so just fall back on option 1.)

Programmatically Unwind Segue?

Found my answer. I didn't name the segue as it said.

Solution: Click on "Unwind segue to 'Exit'", on right panel, 'Storyboard Unwind Segue', you will see.

How to perform an unwind segue from a custom tableview cell?

This sounds like a good job for a protocol/delegate pattern. What I would do is:


  1. Create your unwind segue by connecting it to the viewcontroller not to the tableViewCell. Assign it an identifier you can use later

  2. Create a protocol to which the MyViewController will conform

     protocol unwindHandler{
    func didRequestUnwind()
    }
  3. Implement the protocol in the MyViewController

     extension MyViewController : unwindHandler{
    func didRequestUnwind(){

    performSegue(withIdentifier:"myUnwind",sender:nil)//execute the segue with identifier assigned in 0
    }
    }
  4. Assign the ViewController as the delegate to the tableViewCell in cellForRowAt in the datasource of the tableView

  5. Call delegate?.didRequestUnwind() in the didSelectRowAtIndexPath for the cell(s) you want to have that capability



Related Topics



Leave a reply



Submit