Perform Push Segue After an Unwind Segue

Perform push segue after an unwind segue

A bit late to the party but I found a way to do this without using state flags

Note: this only works with iOS 9+, as only custom segues support class names prior to iOS9 and you cannot declare an exit segue as a custom segue in storyboards

1. Subclass UIStoryboardSegue with UIStoryboardSegueWithCompletion

class UIStoryboardSegueWithCompletion: UIStoryboardSegue {
var completion: (() -> Void)?

override func perform() {
super.perform()
if let completion = completion {
completion()
}
}
}

2. Set UIStoryBoardSegueWithCompletion as the class for your exit segue

note: the action for this segue should be unwindToMainMenu to match the original question

Select exit segue from storyboard
Add custom class

3. Update your unwind @IBAction to execute the code in the completion handler

@IBAction func unwindToMainMenu(segue: UIStoryboardSegue) {
if let segue = segue as? UIStoryboardSegueWithCompletion {
segue.completion = {
self.performSegueWithIdentifier("Categories", sender: self)
}
}
}

Your code will now execute after the exit segue completes its transition

Showing alert after unwind segue stops the segue. How do I make sure alert is shown after unwind segue is completed?

The unwindToFeed method is called before the unwind segue is complete, as you have found.

One approach would be to set a boolean in the unwindToFeed method and then check this boolean in viewDidAppear, when you know the segue is complete. If the boolean is set then you can display the alert:

@IBAction func unwindToFeed(segue: UIStoryboardSegue) {
jsonArray[rowFromShare!]["ApplicationDataUsers"] = jsonFromShare!
tableView.reloadData()
self.unwinding = true
}

override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)
if (self.unwinding) {
self.ShowErrorDialog("Success", message: successMessageFromShare!, buttonTitle: "OK")
self.unwinding=false
}

Is it possible to use an unwind segue from a single modal view controller back to one of multiple instances of the same source view controller?

Apple has a comprehensive technical note on how unwind segues work and how the destination view controller is determined, but, in summary, the process examines the view controller navigation hierarchy to find the first view controller that can handle the unwind segue and is willing to do so.

In your case, this would be the MainVC instance that presented the ModalVC that is unwinding. The unwind segue cannot be handled by a view controller instance that is not in the navigation hierarchy (e.g. An instance of MainVC that did not present the ModalVC)

How to perform segue after current presentation is completed

What you can also do is add a notification on the new controller's viewDidAppear function using NSNotificationCenter. Then, you attach a listener to the notification and when you see the notification show up, you do your next transition.

- (void)viewDidLoad {
[[NSNotificationCenter defaultCenter] postNotification:[NSNotification notificationWithName:@"transitioned to new controller!" object:nil]];
}

elsewhere, just add this to listen to the notification.

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(receivedNotification:) name:@"transitioned to new controller!" object:nil];

Don't forget to stop listening after you receive your notification (unless you desire to remain observing) for this notification, otherwise you will continue observing all notifications throughout your application:

[[NSNotificationCenter defaultCenter] removeObserver:self name:@"transitioned to new controller!" object:nil];

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.

Perform some code before a segue after I push a button in swift

You have a couple of options;

The first is to remove the action from the button in IB and then create a segue between the UIViewController object and your next scene;

@IBAction func onLogoutClick(sender: AnyObject) {
//clear all url chache
NSURLCache.sharedURLCache().removeAllCachedResponses()
//null out everything for logout
email = ""
password = ""
self.loginInformation.setObject(self.email, forKey: "email")
self.loginInformation.setObject(self.password, forKey: "password")
self.loginInformation.synchronize()

self.performSegueWithIdentifier("logoutSegue",sender: self)
}

or you can get rid of the @IBAction method and implement prepareForSegueWithIdentifier

override func prepareForSegue(segue: UIStoryboardSegue!, sender: AnyObject!) {
if segue.identifier == "logoutSegue" {
//clear all url chache
NSURLCache.sharedURLCache().removeAllCachedResponses()
//null out everything for logout
email = ""
password = ""
self.loginInformation.setObject(self.email, forKey: "email")
self.loginInformation.setObject(self.password, forKey: "password")
self.loginInformation.synchronize()
}
}

performing programmatic segue after unwind

I'm not positive of the answer on this one, but I think when "done:" is executed, it's really not executed in that class (meaning the class of the previous screen). It's either executing in an in-between place or in the calling class (meaning the class of the screen you are trying to unwind from). If this is true, it will try to execute prepareForSegue: from the unwind side rather than from V1 side and since there probably isn't a segue.identifier, it just continues on as if it didn't find one....Please don't take this as gospel...I'm guessing here, but I may not be too far off the mark. You could probably put a NSLog in the V2 prepareForSegue: to check it.



Related Topics



Leave a reply



Submit