You can do it the way you describe, or by using a prepareForSegue
override function in the viewController you are unwinding from:
@IBAction func actionForUnwindButton(sender: AnyObject) {
println("actionForUnwindButton");
}
or...
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
println("prepareForSegue");
}
The first example is as you describe. The button is wired up to the unwind segue and to the button action in Interface Builder. The button action will be triggered before the segue action. Perhaps you didn't connect the action to the button in interface builder?
The second example gives you have access to the segue's sourceViewController
and destinationViewController
in case that is also useful (you also get these in the unwind segue's function in the destination view controller).
If you want to delay the unwind segue until the button's local action is complete, you can invoke the segue directly from the button action (instead of hooking it up in the storyboard) using self.performSegueWithIdentifier
(or follow wrUS61's suggestion)
EDIT
you seem to have some doubts whether you can work this by wiring up your button both to an unwind segue and to a button action. I have set up a little test project like this:
class BlueViewController: UIViewController {
@IBAction func actionForUnwindButton(sender: AnyObject) {
println("actionForUnwindButton");
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
println("prepareForSegue");
}
}
class RedViewController: UIViewController {
@IBAction func unwindToRed(sender: UIStoryboardSegue) {
println("unwindToRed");
}
}
BlueViewController has a button that is connected in the storyboard to BOTH the unwindToRed
unwind segue AND the actionForUnwindButton
button. It also overrides prepareForSegue
so we can log the order of play.
Output:
actionForUnwindButton
prepareForSegue
unwindToRed
Storyboard:
EDIT 2
your demo project shows this not working. The difference is that you are using a barButtonItem to trigger the action, whereas I am using a regular button. A barButtonItem fails, whereas a regular button succeeds. I suspect that this is due to differences in the order of message passing (what follows is conjecture, but fits with the observed behaviour):
(A) UIButton in View Controller
ViewController's button receives touchupInside
- (1) sends action to it's method
- (2) sends segue unwind action to storyboard segue
all messages received, and methods executed in this order:
actionForUnwindButton
prepareForSegue
unwindToRed
(B) UIBarButtonItem in Navigation Controller Toolbar
Tool bar buttonItem receives touchupInside
- (1) sends segue unwind action to storyboard segue
- (2) (possibly, then) sends action to viewController's method
Order of execution is
prepareForSegue
unwindToRed
actionForUnwindButton
prepareForSegue
and unwind
messages received. However actionForUnwindButton
message is sent to nil as viewController is destroyed during the segue. So it doesn't get executed, and the log prints
prepareForSegue
unwindToRed
In the case of (B), the viewController is destroyed before the method reaches it, so does not get triggered
So it seems your options are...
(a) use a UIButton with action and unwind segue
(b) trigger your actions using prepareForSegue
, which will be triggered while the viewController is still alive, and before the segue takes place.
(c) don't use an unwind segue, just use a button action. In the action method you can 'unwind' by calling popToViewController
on your navigation controller.
By the way, if you implement a toolBar on the viewController (not using the navigation controller's toolbar) the result is the same: segue gets triggered first, so button action fails.