two segues coming from one view controller, prepareForSegue - ios

Is there a way to have a different prepareForSegue's for different segues coming out the same view controller?
Because I have 2 segues coming out of one view, and there obviously are some workarounds, but I was wondering if it was possible to separate the prepareForSegues into 2 entirely separate methods depending on the segue called.

No, you cannot use two different methods.
You can however call two different methods in a conditional statement like bellow:
You can check which segue was invoked:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
// Get the new view controller using [segue destinationViewController].
// Pass the selected object to the new view controller.
if ([segue.identifier isEqualToString:#"addNewCheckListItem"]) {
} else if ([segue.identifier isEqualToString:#"showExistingCheckListItem"]) {
}
}
But make sure you also set them an identifier from Interface Builder

Related

Perform Segue from Root View Controller of a UIPageViewController

I have a UIPageViewController and have a button in it. Whenever the button is pressed I want to perform a Segue from the parent view controller (which has a navigation controller embedded) to the next view controller in the navigation stack. I also want to be able to pass data through the segue. I've tried a couple of things but I'm very new to iOS development and have not been successful at all.
You need to select the segue in your storyboard and give it a unique identifier and the put that in the code below.
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
if ([segue.identifier isEqualToString:#"YourSegueIdentifier"]) {
// get a reference to the destination View Controller
UIViewController *destinationVC = [segue destinationViewController];
XXYourViewControllerSubclass *yourVC = (XXYourViewControllerSubclass*)destinationVC;
// create the data and pass it to the view controller
id someData = // create your data (unless you have a property holding it already)
[yourVC acceptData:(id)someData]; // make a public method on your VC subclass to accept the data
}
// after this method has returned the seque will be performed
}
Does that make sense?

IOS - Use Segue identifier in child method

This is probably a basic question - but I cant seem to find the answer to it in my searches!
I have a uiview setup which contains two input areas which are linked to a child modal view via separate segues.
this is my parent prepare for segue method -
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:#"goalInfo"])
{
[segue.destinationViewController setYourGoalViewController:self];
}
if ([segue.identifier isEqualToString:#"longGoalInfo"])
{
[segue.destinationViewController setYourGoalViewController:self];
}
}
basically i'd like to determine which segue had been used in the child view so I can apply the relevant filed updates and alter a title/description in the child view. - I basically need something very similar to
if ([segue.identifier isEqualToString:#"goalInfo"])
but i'm not sure how to access this from teh child? Any tips?
The segue identifier is check on the source ViewController during its prepareForSegue: method. What you rather need is during prepare for segue is to set properties on the destination viewController and then when it loads, read these properties and set UI outlets.
Look at this example: I am stuck at presenting a full image on tapping the cell in UICollectionViewController. It's about CollectionVC and its detailVC, but the principle is the same.

Custom initializer for reusable view controller

As you can see from screenshot below, I have view controller, which I am reusing. Depending which tab bar is selected, different view controller instances are created. But depending on tab bar, I would like to initialize my view controller differently, before viewDidLoad. How can I achieve that?
Do it in the prepareForSegue in the container view controller after making sure that your segue's are all named.
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if([segue.identifier isEqualToString:#"embedded"])
{
ReusableViewController* vc = (ReusableViewController*)segue.destinationViewController;
// setup vc customization here
}
}

implement 2 cancel button in a segue

I have a view controller with 2 different segues that goes to 2 different view controller,and i have to implement the cancel button in both the controllers.When i press the cancel button,in both the controller,the view will return to the initial view controller.My question is how can i implement the buttons?When i try with this code the compiler warning:Multiple declaration of method "cancel:" found and ignored.Thank you.
interface:
-(IBAction)cancel:(UIStoryboardSegue *)segue;
-(IBAction)done:(UIStoryboardSegue *)segue;
-(IBAction)cancel:(UIStoryboardSegue *)segue;
implementation:
-(IBAction)done:(UIStoryboardSegue *)segue
{
if([[segue identifier] isEqualToString:#"ReturnInput"]){
AddSightingViewController *addController = [segue sourceViewController];
if (addController.birdSighting) {
[self.dataController
addBirdSightingWithSighting:addController.birdSighting];
[[self tableView]reloadData];
}
[self dismissViewControllerAnimated:YES completion:NULL];
}
}
-(IBAction)cancel:(UIStoryboardSegue *)segue
{
if([[segue identifier] isEqualToString:#"CancelInput"]){
[self dismissViewControllerAnimated:YES completion:NULL];
}
}
I'm not sure of what you're trying to do. But I think the cancel method needs to be in the 2 child View Controllers, not in the main one. One for each controller (and one cancel button for each view). That way you won't have any problems with multiple declarations of a method.
From your code I conclude that you are using (or want use) exit segues for canceling.
First, you should only have one method declaration and implementation for your cancel method in the initial view controller. In your storyboard create exit segues by control-dragging from your cancel buttons to the green exit icon blow the view controller and select the cancel method defined in the initial view controller. Do that for both view controllers. You should also give your exit segues different identifiers in your storyboard (you need to select the segue in the Document Outline to change its identifier).
Then your cancel method in your initial view controller can look something like this:
-(IBAction)cancel:(UIStoryboardSegue *)segue
{
if([[segue identifier] isEqualToString:#"CancelInput1"]) {
// Do something
} else if([[segue identifier] isEqualToString:#"CancelInput2"]) {
// Do something different
}
}
If you don't want to do anything when canceling just leave the method empty.
If you wan't to go back you need to implement an unwind segue.
To do this, define a method to go back on the original view controller (the one you want to go back). You can leave the method empty.
- (IBAction)methodName:(UIStoryboardSegue *)segue
{
}
Then on IB ctrl + drag from the button (or from the view controller) to the green "exit" icon. Select the methodName from the popup menu. If you did it from the view controller set the identifier on the segue and call it with performSegueWithIdentifier: from the button action.
Considerations:
The method name will be detected in every view controller on the storyboard.
You can define the same method name in different view controllers, but when you execute the unwind segue, you will go back to the most recent on the navigation path.

How can I pass extra parameters to a custom segue?

I've been playing around with custom segues in iOS and am trying to use them as much as possible to allow the complete workflow of the application to be visualised in my storyboards. When I create say a popover segue, it knows about the view triggering the segue (it must in order to position the popover), but when I create a custom segue, I cannot find a way of doing the same. Is there a way of accessing the view that initiated the segue in a custom segue? Also, is there a way of passing custom parameters to a segue from Interface Builder, much like you can pass runtime arguments to a view controller?
You can access to the View that has triggered a custom segue by implementing the method:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
... on your View Controller.
On that method, the value of sender will be the view that triggered the segue, if you linked it using Interface Builder. When implementing this method, it is recommended to query what segue has been triggered in the following way:
if ([[segue identifier] isEqualToString:#"segueid"])
... where "segueid" would be the identifier you have given to your segue in Interface Builder.
About your second question, I don't know any way to specify parameters for a segue in Interface Builder, but you can use the same "prepareForSegue" method, to pass them from your View Controller at Runtime.
Imagine that your custom segue has a property called animationStyle
if the perform method, you can have the following:
- (void)perform
{
switch (self.animationStyle) {
case 0:
// TODO Perform animation type 0
case 1:
// TODO Perform animation type 1
}
}
Then, let's say you have a couple of View Controllers where you want to use that custom segue. In the first one you can implement the performSegue method like:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:#"yourCustomSegueID"]) {
((YourCustomSegueClass *)segue).animationStyle = 0;
}
}
While in the second view controller you can implement it like:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:#"yourCustomSegueID"]) {
((YourCustomSegueClass *)segue).animationStyle = 1;
}
}
... So effectively, you are reusing the same custom segue class for getting different effects. It is still true that IB will not let you configure the segue directly, but there's no way around that as far as I know.

Resources