This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Passing variables between view controllers
Let's say I have 3 buttons in the same ViewController(FirstController) with tags from 1-3. All three buttons opened a new ViewController(SecondController). But how can I, in the SecondController, check what button was pressed to get here, or maybe what segue was used? So the SecondController can perform different depending on which button was pressed to open it. I was maybe thinking about a switch and case.
There are 2 possible ways of doing this.
One way is to assign a unique segue to each button. On the method prepareForSegue: you identify the button and give that information to the destinationViewController:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:#"Button1Segue"]) {
[segue.destinationViewController setButton:1];
}
if ([segue.identifier isEqualToString:#"Button2Segue"]) {
...
}
The other way would be to create a property where you store the last pressed button.
- (IBAction)buttonTap:(id)sender {
self.lastPressedButton = sender.tag;
}
and in prepareForSegue: you would do:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:#"SecondControllerSegue"]) {
[segue.destinationViewController setButton: self.lastPressedButton];
}
}
Hope it helps
if (button.tag == 0) {
NSLog(#"Button one.");
} else if (button.tag == 1) {
NSLog(#"Button two.");
}
You would put something like this in the method that occurs just before the action of your three buttons. That could be viewWillDisappear, prepareForSegue, etc.
Best of luck!
Related
In -prepareForSegue:sender:, how do I check if the sender was the view controller in which the -prepareForSegue:sender: is written?
In other words, how do I compare the sender argument to see what was passed when calling -performSegueWithIdentifier:sender:
I tried:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:#"identifier"])
if ([(MyViewControllerClass *)sender isEqual:self]) {
// stuff
} else {...}
}
}
Also tried == in place of isEqual:.
The else part is always executed.
you can try this
if([sender isKindOfClass:[MyViewControllerClass class]){
//do stuff
}
Update: First below code was crap ofcourse, here the version that does make sense:
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
[self performSegueWithIdentifier:#"segueIdentifier" sender:self];
}
- (void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if (segue.sourceViewController == sender) {
NSLog(#"i have been the sender");
}
}
Stupid last version as reference what you should not do - answer to fast:
I think you don`t want to check the sender. The sender could also be a Button activating the segue - i guess that you want to check against the sourceViewController.
- (void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if (segue.sourceViewController == self) {
NSLog(#"i have been the source");
}
}
This will check if the segue will transition from the current ViewController.
I have two view controllers: CropImageViewController and ImageCropperViewController
In CropImageViewController I have this method:
-(void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
NSLog(#"prepareForSegue called");
if([segue.identifier isEqualToString:#"goBack"])
{
NSLog(#"processedText = %#",self.processedText);
[segue.destinationViewController setProcessedText:self.processedText];
}
}
Then, in ImageCropperViewController, I have this:
-(void)viewWillAppear:(BOOL)animated
{
NSLog(#"view will appear called");
//self.processedImageLabel.text = self.processedText;
NSLog(#"processedText = %#",self.processedText);
NSLog(#"testLabel: %#",self.testField.text);
}
This is the console output. For some reason, "processedText" is always NULL no matter what.
2014-05-23 16:51:43.488 ImageCropper[9294:60b] prepareForSegue called
2014-05-23 16:51:43.490 ImageCropper[9294:60b] processedText = E33
===..., ____
2014-05-23 16:51:43.493 ImageCropper[9294:60b] view will appear called
2014-05-23 16:51:43.494 ImageCropper[9294:60b] processedText = (null)
I see your segue "goBack". Are you come back after pushed CropImageViewController from ImageCropperViewController?
So in this case you shouldn't use a segue. You should write an IBAction for your button (or i don't know what you have to come back) and when you press it do:
[self popViewControllerAnimated:YES];
but before this, you should call the delegate to pass the new value:
[_delegate changeProcessedText:self.processedText];
Obviously i assume that you know how implement a delegation pattern.
Another way could be use KVO, so observing from the first viewController, the processedText.text value in the second viewController.
I have an app having 7 screen. On the screen 7 i have a button that does valiation and submits data and then it jumps to screen 1 using modal segue.
But ,I only want to move screen1 if the validation succeeds or else i dont want to move to screen1.
Currently its moving to screen 1 independent of validation.
button click code is as below
- (IBAction)submitButtonActionForDemo:(id)sender
{
if (![JLTValidator validateFields:#[_authRepresentative, _acceptDeclarationStatement,_homeTeamRepName,_homeTeamRepPosition,_awayTeamRepName,_awayTeamRepPosition]])
{
// how to disable a modal segue here.
return;
}
}
JLTValidator is my validating class here.
Pls suggest/help. Thanks in adv.
If you want to only allow the segue some times, you need to "name" the segue in InterfaceBuilder, then implement this routine:
- (BOOL)shouldPerformSegueWithIdentifier:(NSString *)identifier sender:(id)sender {
if ([identifier isEqualToString:#"your segue name"]) {
return false;
}
return true;
}
In this case, I am assigning values below to stringToDisplay and want to send them to SegViewController, which also retains stringToDisplay. Do I need to use cell.textLabel.text here with isEqualToString: #"Fire House Gallery? Would I use indexPath or UITableViewCell here?
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
SegViewController *seg = segue.destinationViewController;
seg.delegate = (id)self;
if ("......" isEqualToString: #"Firehouse Gallery"])
{
seg.stringToDisplay = #"Firehouse Gallery";
}
else
{
seg.stringToDisplay = #"Frog Hollow Craft Center";
}
}
Thank you,
Greg
The short answer:
You shouldn't derive data from your table view cells because they are your view. You should be "deriving data" from your model.
The longer answer:
Determining how to configure your segue depends on how you are calling it:
If you are calling it in code (using performSegueWithIdentifier:sender) then pass your string as the "sender" in your method call.
If you have setup the segue in your storyboard, then you should use different segues for each possibility, and check the segue identifier to determine which string that you should pass.
I found an answer for what I was looking for. I now have ONE segue link between two UIViewcontrollers, with the segue identifier called #"seg". For a place named Radio Bean, I use the following when the "Radio Bean" cell is pressed:
if ([cell.textLabel.text isEqualToString: #"Radio Bean"])
{
self.stringToDisplay = #"Radio Bean";
[self performSegueWithIdentifier:#"seg" sender:self];
}
Then, in prepareForSegue I DO NOT specify segue identifier but use the following:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
SegViewController *seg = segue.destinationViewController;
seg.delegate = (id)self;
if ([self.stringToDisplay isEqualToString: #"Radio Bean"])
{
seg.stringToDisplay = #"Radio Bean";
}
}
This successfully passes "Radio Bean" to the next UIViewcontroller, and I can include multiple place options with the use of only ONE segue link, so, no need for multiple links.
Sorry if the title isn't very clear, but hopefully I can elaborate here.
I have a ViewController MatchLineupViewController, which displays 22 buttons to represent rugby players on a team. When the user taps any of these buttons, a modal segue is called programmatically in the following method:
- (IBAction) showSquadSelector:(UIButton *)sender {
[self performSegueWithIdentifier:#"SeguePopupSquad" sender:sender];
}
The modal ViewController which is then displayed is called SquadSelectViewController. It passes back a selected player object to the MatchLineupViewController, which is acting as a delegate. This works perfectly.
However, I want to assign the profile_picture attribute of the returned object to the UIButton that sent the segue in the first place.
EDIT - The returned object is an NSDictionary as shown in the following code:
- (void) selectPlayer:(NSDictionary *)player forButton:(UIButton *)sender {
[sender.imageView setImage:[UIImage imageWithContentsOfFile:[player objectForKey:#"profile_picture"]]];
}
How would I go about doing this? If you require any further code to understand what I am asking, I can provide it.
Many thanks,
Chris
EDIT -
- (IBAction) showSquadSelector:(UIButton *)sender {
[self performSegueWithIdentifier:#"SeguePopupSquad" sender:sender];
}
- (void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:#"SeguePopupSquad"]) {
SquadSelectViewController *ssvc = (SquadSelectViewController *) segue.destinationViewController;
ssvc.myDelegate = self;
ssvc.senderButton = sender;
}
}
- (void) selectPlayer:(NSDictionary *)player forButton:(UIButton *)sender {
[sender.imageView setImage:[UIImage imageWithContentsOfFile:[player objectForKey:#"profile_picture"]]];
NSLog(#"%#", [player description]);
NSLog(#"%#", [sender description]);
}
You can forward the sender of your showSquadSelector: method to the segue, like this:
[self performSegueWithIdentifier:#"SeguePopupSquad" sender:sender];
The sender of the segue would be the button that triggered the segue, so the code triggered from the segue would know what button has triggered it: your prepareForSegue: would have the correct UIButton. You can now add it to the returned dictionary at a predetermined key (say, #"senderButton") and examine it upon the return from the segue.