Upon clicking on the button, I want the user to navigate to another view. The following code works fine. However, I want to pass some values as well to the next screen. How am I suppose to do so ?
- (IBAction)buttonClick:(id)sender {
[self performSegueWithIdentifier:#"segueviewc" sender:self];
}
I also tried the following code and it works but the page navigates twice to the MyV viewcontroller. From buttonClick event and from prepareForSegue method. How can I prevent this ?
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
MyV *myv = (MyV*) segue.destinationViewController;
myv.navigationItem.title=#"Hey";
myv.arr=data;
}
Open the storyboard check if the segue is directly connect from the button to the next view. If it does, you can simply delete the line.
[self performSegueWithIdentifier:#"segueviewc" sender:self];
i think the problem is, the segue is directly connected from the button action to the next view, and within the button action, you call the segue again!
cheers
You don't have to perform the segue on your button click. If your button is triggering the segue, it will be performed automatically.
Remove the line -
[self performSegueWithIdentifier:#"segueviewc" sender:self];
from your method -
- (IBAction)buttonClick:(id)sender {
Also you must ideally check which segue is being performed, so that you can code according to the navigation being performed...
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
if ([segue.idenifier isEqualToString:#"segueviewc"])
{
MyV *myv = (MyV*) segue.destinationViewController;
myv.navigationItem.title=#"Hey";
myv.arr=data;
}
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:#"segueviewc"]) {
MyV *myv = (MyV*)[self.storyboard instantiateViewControllerWithIdentifier:#"yourStoryboardID"];
myv.navigationItem.title=#"Hey";
myv.arr=data;
}
}
And you do not need IBAction method.
There are 2 ways to trigger a segue:
1. You trigger it as an action from your button directly to the new view controller
2. You trigger the segue from one view controller to the second view controller.
I am guessing you are connecting it via 1st approach. Hence you should not trigger it from IBAction.
Related
I'm trying to create a manual segue, which happens only if there is a certain conidition (a successful login).
The steps I have followed are these:
1) I've created a button in source viewcontroller, and i connected the button with a drag with the destination viewcontroller.
2) I set the identifier for the segue, calling it login_ok
3) I've created a -(IBAction)buttonPressed:(id)sender
Now, I tried to make an example, to see if the work or not. I wrote:
- (IBAction)buttonPressed:(id)sender
{
BOOL test = false;
if(test == true)
{
[self performSegueWithIdentifier:#"login_ok" sender:self];
}
Theoretically, the segue should not work, because i set test=false, and i said the segue should work only if test=true.
But the segue works and makes me go to the destination viewcontroller.
Why?
If you connected the button with a drag to the destination controller, it should segue anyway.
You need to connect the segue between screens and not from the button to the screen. Then, you can control your segue from the code.
You should define your segue between controllers not from button to the controller. Defining segue between view controllers is more useful than defining segue from any component to a view controller, because when you want to use a condition for any action, you can use these two methods effectively
[self performSegueWithIdentifier:#"segueID" sender:self];
and
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
For example:
- (IBAction)buttonPressed:(id)sender
{
BOOL test = YES;
if(test == YES)
[self performSegueWithIdentifier:#"login_ok" sender:self];
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:#"login_ok"])
{
YourNextController *controller = [segue destinationViewController];
controller.welcomeText = #"Hi! Test is true congratulations";
}
}
Especially passing data from controller to another one, this way is always useful.
I am creating a simple game that has a specific image,like a menu button, with a tap gesture. The tap gesture calls a method and goes to a View controller(menu of my game). My problem is when I tap this image, it is ignoring the second action. The image below describes better my tap gesture.
PS: getBackToMenu is my method that sets some attributes of my game.
what you are doing here is triggering segue directly from button. Because of this segue is being performed first.
Do One thing remove segue from button to view controller and create segue between controllers with some identifier.
then implement this method
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
if ([[segue identifier] isEqualToString:#"YOUR_SEGUE_IDENTIFIER"])
{
YourViewController *vc = [segue destinationViewController];
[vc setMyObjectHere:object];
}
}
Then on button press event perform segue using this method
- (IBAction)buttonPressed:(id)sender{
//Do your primary task here Then Call performseguewithidentifier method
[self performSegueWithIdentifier:#"YOUR_SEGUE_IDENTIFIER" sender:sender];}
When you are about to perform the segue action, you can add some codes in
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
You can get the destination controller using segue.destinationController, and then set some attribute there as just passing some data.
By the way, you can identify which segue works, add
if ([segue.identifier isEqualToString:#"yourSegueName"])
Hello I have a button that must present a modal view controller when tapped
Here is the action:
- (IBAction)addNewLevelAction:(id)sender
{
[self performSegueWithIdentifier:kNewLevelConfigureSegue sender:self];
}
in prepareForSegue:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:kNewLevelConfigureSegue]) {
PSLevelConfigViewController *dest = (PSLevelConfigViewController *)[segue destinationViewController];
dest.delegate = self;
}
}
However when I tapp it I get:
Warning: Attempt to present <PSLevelConfigViewController: 0x98cbd00> on <UINavigationController: 0x98aac70> while a presentation is in progress!
Why is this? There is no other presentation there...
If you perform the segue programmatically, the segue must be connected to the controller and not directly to the button.
Check if your storyboard is set correctly (post some screenshots if you need help).
In such situation, if your segue is connected to the button AND, at the same time, to an action that performs it programmatically, your segue will be performed twice, and the second perform will cause that error.
Okey guys, here's the deal...
I'm trying to connect two views with one segue and writing in Label a tag from clicked button. I hope you know what I mean...
Here's the example:
Title view appears and you have to choose the difficulty 1-3 (tag values of buttons) and after clicking your're moved to game view but you'd like to use tag values from title view buttons in game logic.
Here's the sample screen:
This is what I've found and this perfectly suits!
// When any of my buttons are pressed, push the next view
- (IBAction)buttonPressed:(id)sender
{
[self performSegueWithIdentifier:#"Segue" sender:sender];
}
// This will get called before the view appears
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:#"Segue"]) {
// Get destination view
SecondView *vc = [segue destinationViewController];
// Get button tag number (or do whatever you need to do here, based on your object
NSInteger tagIndex = [(UIButton *)sender tag];
// Pass the information to your destination view
[vc setSelectedButton:tagIndex];
}
}
And here is the link to whole topic.
Set your buttons to trigger the segue that presents the second view controller.
In your first view controller, implement - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender and use the sender to retrieve the tag.
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.