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?
Related
I am new to IOS i created two view controller.First view controller contain tableview as table1 and Second view controller contains button. I want to pass table1 to second view controller and unhide table1 in button action.
pop up for second view controller
first view controller after button action in second view controller
For instance, consider I had two view controllers. The first contains one button and the second needs to know information on the first view . You could wire the buttons up to an IBAction in your code which uses performSegueWithIdentifier: method, like this...
// When any of my buttons are pressed, push the next view
- (IBAction)buttonPressed:(id)sender
{
[self performSegueWithIdentifier:#"MySegue" sender:sender];
}
// This will get called too before the view appears
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
// Make sure your segue name in storyboard is the same as this line
if ([[segue identifier] isEqualToString:#"YOUR_SEGUE_NAME_HERE"])
{
// Get reference to the destination view controller
YourViewController *vc = [segue destinationViewController];
// Pass any objects to the view controller here, like...
[vc setMyObjectHere:object];
}
}
For more information you can see this: http://www.appcoda.com/storyboards-ios-tutorial-pass-data-between-view-controller-with-segue/
I'm trying to use a custom segue (at bottom) to present a view controller modally with a blur view. I need to instantiate the view controller with properties before I present the view controller.
Instating the VC works great when I am using pushVC, but when I use perform segue with identifier, I don't see an option to choose an already instantiated VC.
CustomViewController* VC = [self.navigationController.storyboard instantiateViewControllerWithIdentifier:#"customVC"];
[self.navigationController performSegueWithIdentifier:#"blurSegue" sender:self];
How can I perform the custom segue and force it to use the view controller I allocated (called VC above)?
https://github.com/AlvaroFranco/AFBlurSegue
I need to instantiate the view controller with properties before I
present the view controller.
Why do you have to instantiate CustomViewController before triggering the segue. That shouldn't be necessary, if you need access to a property of CustomViewController before it's shown, you can set it in prepareForSegue.
Try this:
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:#"blurSegue"]) {
CustomViewController *customViewController = (CustomViewController *)segue.destinationViewController;
customViewController.propertyToSet = XXX; // set the property here
}
}
Ah, by the way, instead of
[self.navigationController performSegueWithIdentifier:#"blurSegue" sender:self];
just use:
[self performSegueWithIdentifier:#"blurSegue" sender:self];
I have a couple of "ViewControllers" and one for Update a picture in an iOS app.
The first one has a button when tapped asks if the user wants to use gallery photo or camera.
Now i am presenting this controller by using presentViewController on self.
But when the second view controller is presented i want to set the UIImagePicker source according to what the user has passed in.
I have made 2 different methods. one with camera source and one with "photoslibrary".
I don't know how to invoke one of these methods based on the use choice from the previous controller.
Am i going the right way with this approach? or should i just have one controller?
Basically there are two ways of passing data to a view controller.
Storyboard
If you are working with storyboard segues (that is, control drag from your "root" view controller to the destination view controller, choose a transition style and define a identifier), you can present the view controller
via
[self performSegueWithIdentifier:#"yourSegueIdentifier" sender:self];
Most of the times your destination view controller will be a custom class, so define a public property to hold the data you want to pass through. Then implement the following in your "root" view controller
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
// Setup the location menu delegate
if([segue.identifier isEqualToString:#"yourSegueIdentifier"]) {
// The custom class of your destination view controller,
// don't forget to import the corresponding header
ViewControllerCustomClass *vc = segue.destinationViewController;
// Set custom property
vc.chosenImageId = self.chosenImageId;
// Send message
[vc message];
}
}
Hints:If your destination view controller is the root view controller of a navigationViewController you can access it via [[segue.destinationViewController childViewControllers] objectAtIndex:0]; Additionally, as senderis an id, you can "abuse" it to pass any object through, just as a NSDictionary, for example.Also note, that when I am referring to the root view controller, I am talking of the view controller from which we segue to the destination from.
Programmatically
ViewControllerCustomClass *vc = [[ViewControllerCustomClass alloc] init];
vc.chosenImageId = self.chosenImageId;
// If you want to push it to the navigation controller
[self.navigationController pushViewController:vc animated:YES];
// If you want to open it modally
[self presentViewController:vc animated:YES completion:nil];
You can use inheritance, make your previous controller superClass, and invoke method in presentViewController in viewDidload.
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.
Here's my problem. With Storyboard's segue I am having a popover segue for a bar button. The UIViewController inside the UIPopoverController requires to load the data from a server. With Storyboards, everytime I close the popover the view is released so whenever the popover appears again it tries to load data again from server. I dont want this behavior. How can I prevent Storyboard from resetting the view controller inside popover controller? Something like what UITabBarController does. UITabBarController calls viewDidLoad for the first time and for the subsequent tab switches viewWillAppear is called.
Segue is designed so. Every time you do segue - view will be loaded.
If you need to store it's data - you should store it outside popover and use this method
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
if ([[segue identifier] isEqualToString:#"your segue identifier"])
{
//get popover
ViewController *vc = [segue destinationViewController];
//Set popover data to vc here
}
which calls before segue, and in this method set data to popover.
If you will use it - don't forget to set Segue identifier in Interface Builder.