简体   繁体   中英

iOS Xcode (swift) - how to execute code after unwind segue

I perform a segue from scene 1 to scene 2. I then return from scene 2 to scene 1. How do I not only pass data from scene 2 to scene 1 but detect in scene 1 that I've returned from scene 2 and execute code in scene 1?

In Android I do this with startActivity and onActivityResult.

Introducing Bool state like the other answer's suggesting is very bad and must be avoided if possible as it greatly increases the complexity of your app.

Amongst many other patterns, easiest one to solve this kind of problem is by passing delegate object to Controller2 .

protocol Controller2Delegate {
  func controller2DidReturn()
}

class Controller1: Controller2Delegate {
  func controller2DidReturn() {
    // your code.
  }

  func prepareForSegue(...) {
    // get controller2 instance

    controller2.delegate = self
  }
}

class Controller2 {
  var delegate: Controller2Delegate!

  func done() {
    // dismiss viewcontroller

    delegate.controller2DidReturn()
  }
}

States are evil and is the single biggest source of software bugs.

you could do it like this:

class SourceViewController: UIViewController {
  var didReturnFromDestinationViewController = false

  @IBAction func returnToSourceViewController(segue: UIStoryboardSegue) {
    didReturnFromDestinationViewController = true
  }

  override func viewWillAppear(animated: Bool) {
    super.viewWillAppear(animated)

    if didReturnFromDestinationViewController == true {
      // reset the value
      didReturnFromDestinationViewController = false

      // do whatever you want
    }
  }
}

The problem I was having was that I was trying to show an alert dialog after the unwind segue had finished. So my View Controller 2 performed an unwind segue to View Controller 1. What I found is that the code that runs after the unwind segue method is called runs before View Controller 2 is dismissed, so when I tried to show an alert dialog, it would disappear as soon as View Controller 2 was dismissed.

If the other solutions don't work for you, do what I did. I added a viewWillAppear override to my class and dismissed the parent controller there, then added the code for my alert dialog after that. To make sure viewWillAppear wasn't showing the alert dialog the first time View Controller 1 was presented, I set up an if statement checking for the name of a variable that I declared in the class and had set equal to "". Then in View Controller 2 I passed some text in the variable back to View Controller 1, so when the if statement runs it tests the variable not equal to "", and when it finds it's not, the code is run. In my case the variable was named "firstname".

override func viewWillAppear(_ animated: Bool) {

    if firstname != "" {
        self.parent?.dismiss(animated: true, completion: nil)
        //CustomViewController?.dismiss(animated: true, completion: nil)
        let alertController = UIAlertController(title: "Hello", message: "This is a test", preferredStyle: .alert)
        let defaultAction = UIAlertAction(title: "Close Alert", style: .default, handler: nil)
        alertController.addAction(defaultAction)
        present(alertController, animated: true, completion: nil)
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM