I am not a regular user of interface builder but I have to use it for this project.
I am using storyboards and have managed to create a push segue from one view controller to another. Lets call it from A to B. Now I am trying to unwind that segue and return from B to A.
I do not need any information to be passed between controllers. I just need to go back.
I have a UIBarButtonItem navigation bar of B, and I have followed this tutorial.
I did this:
A) Created this method on B
- (IBAction)backToViewControllerOne:(UIStoryboardSegue *)segue {
NSLog(#"from segue id: %#", segue.identifier);
}
B) The tutorial author says: "Link this method to a button in the view that you want to unwind from." but this cannot be done because the method has this parameter :(UIStoryboardSegue *)segue and Xcode will not allow a button to be linked to this method, because it expects the method to have this parameter :(id)sender. If I change the parameter to that, the triggered segue cannot be linked.
C) link the button to the green exit on storyboard, choosing the method on 1. OK, did that.
Did all this and clicking on the button does nothing. Not even the action is triggered.
How do I solve that puzzle?
A method with with a particular signature, an IBAction with an argument of type UIStoryboardSegue, needs to be in the controller that you are unwinding to. That (and any other methods like it that you might have in other controllers) will show up in the exit button (of the controller you're unwinding from) when you control-drag to it.
Related
In my Xcode interface builder, I'm not finding unwind-segue exit action. what is the problem in this case?
The list of segues available in that Exit panel is populated based on the unwind segues you have defined as #IBActions in your other view controllers, for example:
#IBAction func unwindFromExampleViewController(segue: UIStoryboardSegue) {
}
This tells iOS that the UIViewController with this action in it (let's call it ViewControllerA) is ready to handle the unwind from the UIViewController in your screenshot (ViewControllerB).
Have you implemented such an action in another VC yet? Once you've have that in place (in one or more VCs), you'll be able select 'unwindFromExampleViewController' from the list of Exit options for ViewControllerB.
FYI: you can define the same unwind action in multiple VCs if you need to; iOS will pick the 'nearest' one to unwind to when it gets called.
You can find more details on using unwind segues in this question here.
Created a button to exit from a second ViewController to the previous ViewController. I've read in tutorials that this should be by using the "EXIT" in the view controller. (control+click+drag the button to EXIT).
I have created an "exit" button on this second controller, and a method on the ViewController class to hook up with the control+click+drag exit segue. This method is completely empty:
- (IBAction) unwindToMainMenu:(UIStoryboardSegue *) unwindSegue
{
}
And yet, when I press the button it returns back to the previous ViewController as I intended, but I was expecting nothing should happen (as the method has no content).
I assume the StoryboardSegue object passed into this method is this EXIT that I dragged the button into, but there's no code to handle that object.
EDIT:
Also, I am not returning anything, yet the declaration of the method says it should return an IBAction. Why is the compiler not complaining?
Can you help me understand what am I missing?
Welcome to stackoverflow,
Firstly, IBAction is just a way to say 'you can drag to this' for Xcode, it's not really like a return type, i just consider it void.
Secondly, it is working as intended :D Basically you can now call this method like you have with hooking it up with the storyboard or you can manually call it like:
[self performSegueWithIdentifier:#"unwindToMainMenu" sender:self];
and all of the variables that you have set in your current view controller will be passed back to the source view controller that you're unwinding to.
e.g
-(IBAction)prepareForUnwind:(UIStoryboardSegue *)segue {
if ([segue.identifier isEqualToString:#"unwindToMainMenu"]) {
VcExample *vcExample= (VcExample *)segue.sourceViewController;
NSString *string = vcExample.aVariableNameYoureInterestedInFromTheVCYouUnwoundFromLolThisIsLong;
}
}
The unwind segue is just a built in feature, if you hook that button up to it, it will segue
In storyboard we have great feature that allow us to make Show (e.g. push). So seems the logic is next:
If we don't have navigation controller then view controller will use present modal logic. My question is there any inverse action that I can use with Show?
I have a UIButton that close current view controller screen:
- (IBAction)onTappedCloseButton:(id)sender
{
[self.navigationController popViewControllerAnimated:YES];
}
But in case if I don't have navigation controller, how can I simple use inverse action to go back? So my solution is to check if self.navigationController is nil then use dismissing option:
[self dismissViewControllerAnimated:YES completion:nil];
But maybe there is another cool solution like Show (e.g push). But Close (e.g. pop)?
Yes, you can use an unwind segue to go back, and it will be the reverse of whatever the forward segue was.
You have two options on how to do this:
1) The Unwind segue
To make an unwind segue you have to add a method in the view controller you want to "unwind" to with the following format:
-(IBAction)someSelectorName:(UIStoryboardSegue *)sender;
You will then be able to drag from your UIButton up to the "exit" icon in your storyboard.
Wire it up to the selector you just defined and UIKit will figure out how to get back to that view controller without you having to write any code. This can be especially useful as it can figure out when it needs to call -dismissViewControllerAnimated: more than once and can call those methods successfully. It can even unwind from within a view controller embedded in a navigation controller when the view controller you're unwinding to has the navigation controller presented on top of it. (i.e. it will do a dismissViewController instead of a pop to unwind)
2) The Custom unwind method
Say you don't want to or cant trigger this action from a storyboard. There is still an option and its detailed over at this question here:
Whats the programmatic opposite of showViewController:sender:
The gist is you can write your own generic dismiss method by implementing categories on the UIKit container View controllers (or on your own container)
I'm know how to use storybaord drag line to exit use unwind method.
I have four uiviewcontroller (A~D).
I write the code in B UIViewcontroller
-(IBAction) backToMenu:(UIStoryboardSegue *) segue
{
}
I know It's can drag the action to the green button(exit) to set the back action in the D UIViewcontroller.
It will show the backToMenu method name and they can link.
Now, I want to use programming to implement the drag to green button (exit) action.
But I don't know how to write this part.
I don't use popViewControllerAnimated method. because I need from D UIViewcontroller back to the B UIviewcontroller.
And D UIviewcontroller have a condition if a variable is YES, will unwind to the B(backToMenu) method.
Have any one know how to use the code implement the "drag line to the exit button" action?
(I am use navigation push, not modal)
Thank you very much.
You should've read the docs.
[self.navigationController popToViewController:vcB animated:YES];
I am creating an app using iOS 5 SDK. I managed to push views using the Storyboard's Segues, but I cannot find the proper way to pop the current view and go back to the previous one.
I am not using any navigationController (the app doesn't have any top or bottom bars).
I don't think using modal or push segue the other way would be the solution as it instantiates a new controller.
Do I have to use a custom Segue with the opposite animation and deletion of the view at the end ? Or is there a better way ?
Storyboards in iOS 5 don't provide a "no-code" way to return from a segue -- that's something you'll need to implement yourself.
If you use "push" segues (which require a navigation controller), use the navigation controller's popViewControllerAnimated: method to undo the last push segue. (Or other methods to undo more; see the UINavigationController documentation.)
If you use "modal" segues, call dismissViewControllerAnimated:completion: on the view controller which presented the current view controller (which you can get from its presentingViewController property).
Update: In iOS 6 and later there's unwind segues for going "back" in a storyboard. It's still not a no-code solution -- and it shouldn't be, because you need to be able to do things like differentiating between "Done" and "Cancel" exits from a modal view controller. But it does let you put more of the semantic flow of your app into the storyboard. Apple has a tech note that describes them in detail, and they're also covered in the video from WWDC 2012 Session 407.
You could try calling [self dismissViewControllerAnimated:YES completion:nil]; from the controller you want to dismiss (whether the controller has been pushed, or shown modally).
Here is the related documentation : UIViewController Class Reference
The presenting view controller is responsible for dismissing the view controller it presented. If you call this method on the presented view controller itself, it automatically forwards the message to the presenting view controller.
Just to clarify.
In the class that was pushed. Simply wire up the following and the controller and view will be popped off.
[self.navigationController popViewControllerAnimated:YES];
Create Segue type "Custom" on your stroyboard. This can be from a button.
Create a new UIStoryboardSegue class named "popSegue"
In the popSegue.m file add the following;
-(void)perform{
UIViewController *sourceViewContreoller = [self sourceViewController];
[sourceViewContreoller.navigationController popViewControllerAnimated:YES];
}
-In the storyboard editor.
-Select the segue and change the Segue Class to "popSegue"
-Set the Identifier to "popSegue"
Done!
You can use the same "popSegue" class throughout your project.
Hope this helps
I'm using Xcode 5 also and here's how it's done. First, in the view code file that pushed the other, create an IBAction method in the .h file such as this:
- (IBAction)exitToHere:(UIStoryboardPopoverSegue *)segue sender:(id)sender;
Then in the .m file add this:
- (IBAction)exitToHere:(UIStoryboardPopoverSegue *)segue sender:(id)sender {
}
You can add any cleanup code you want executed in this method. Next go to your storyboard and select the pushed view. I assume you've got some kind of button on the view that the user taps to signal he's finished. Click on that button, hold down the key and drag to the the green box below the view which is the Exit. Release the mouse button but continue to hold the key. A popup will appear and your method will show in the list. Select that method. Now when the user clicks on the button, the view will pop and you'll be returned to the starting method.