I am doing a custom Segue on Storyboard and I have a button that contains this code:
[self performSegueWithIdentifier:#"line3" sender:sender];
By clicking on the button it works well. The problem I am running into that this code only works inside a button function not inside a void function. I tried clicking on the button and it works well. When I paste it inside just a void function it gives me an error complaining about the sender. I tried changing it to void but nothing happens. Can you give me some insight on to fix this issue. I am checking a UserDefault and it matches what I am looking for then I want to to perform this code: [self performSegueWithIdentifier:#"line3" sender:sender];
-(IBAction)LoginAttemp:(id)sender{
[self performSegueWithIdentifier:#"line3" sender:sender];
}
-(void) LoginFailed{
[self performSegueWithIdentifier:#"line3" sender:sender];
}
Error I Get:
Use of undeclared identifier 'sender'
Any insight?
change
[self performSegueWithIdentifier:#"line3" sender:sender];
to
[self performSegueWithIdentifier:#"line3" sender:Nil];
the sender is:
The object that you want to use to initiate the segue. This object is
made available for informational purposes during the actual segue.
void isn't the issue. The issue is that sender is not a reserved word. It's one of the parameters to your IBAction:
-(IBAction)LoginAttemp:(id)sender{
See? Right there at the end. That's Objective-C equivalent of IBAction LoginAttemp(id sender)
If you don't have a sender, you can pass nil or self. Using self would be preferred.
-(void) LoginFailed{
[self performSegueWithIdentifier:#"line3" sender:self];
}
Related
I found a really good walk through of how to pass string values back from a ViewController to a calling ViewController and got it working perfectly. The example is really very good.
https://www.youtube.com/watch?v=YVikeoR3gYg
That said, the technique for passing back content seems relatively straight forward now that I have seen it, even if it's not that intuitive.
The example code however only includes two controllers. When I replicated the code using a much more detailed Storyboard, the code simply doesn't work. In my test app, I even embedded the calling Controller inside a NavigationController to see whether this would have an affect, but it still continued to work fine.
In my application, the ViewController is embedded within a NavigationController that is called via a SWRevealController segue class. I don't know if this is important or relevant but I am mentioning it.
I then call a CollectionViewController to choose an icon that should be passed back to the calling ViewController.
When I select the icon, I correctly identify the icon and pop
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath {
selectedIcon = [placeIcons objectAtIndex:indexPath.row];
NSLog(#"In IconCollectionViewControlled - selected %#", selectedIcon);
NSString *itemToPassBack = #"12345"; // Just testing any old string here...
// [self.delegate passBackIcon:selectedIcon]; // commenting out while testing
[self.delegate passBackIcon:itemToPassBack];
[self.navigationController popViewControllerAnimated:YES];
}
I get a correct trace suggesting that the right icon is selected. I would then expect that the text '12345' would be passed back to the calling Controller.
In my calling Controller, I have the following:
- (void)passBackIcon:(NSString *)iconName {
NSLog(#"Icon to use is %#", iconName);
}
But this just isn't being called at all (or at least I'm not seeing the NSLog being shown. It's just being ignored.
The delegate is being correctly declared as far as I can tell.
Am I missing something?
assuming you are working with segues, in the method prepareSegue you should setting the delegate
for Example :
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:#"YOUR_SEGUE_IDENTIFIER"] ) {
DestinationVc *vc = (DestinationVc *)segue.destinationViewController;
[vc setDelegate:self];
}
}
Hope it works for you
I've found this to be the easiest way to pass string and other information around using a tableView.
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
ViewControllerYouWantToPassToo *result = [self.storyboard instantiateViewControllerWithIdentifier:#"NameOfTheViewController"];
result.stringName = #"12345" // String Name is a NSString property you set up in the ViewController you want to pass too
[self.navigationController pushViewController:result animated:YES];
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}
I suggest you wrapping your delegate in a check to see that it is valid and that it has adopted the respective method (if optional).
if(self.delegate && [self.delegate respondsToSelector:#selector(passBackIcon:)]){
[self.delegate passBackIcon:itemToPassBack];
}else{
NSLog(#"Your delegate is not setup correctly");
}
If it enters the else, you have not set the delegate properly..ie you likely never did
self.delegate = SomeInstanceOfAClassThatAdoptsYourDelegate;
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 a button that will segue to another View Controller. In shouldPerformSegueWithIdentifier I check the identifier and returns NO for this certain button after calling my own method nextClicked.
In nextClicked I do a HTTP Request and check some stuff, and then if everything is OK I do
dispatch_async(dispatch_get_main_queue(), ^{
[self performSegueWithIdentifier:#"getstartednext" sender:self];
});
The problem is that I get no animation now... The segue is of type modal. If I return YES in shouldPerformSegueWithIdentifier and don't to the segue programmatically later, the animation appears and everything is as it should.
You are misusing shouldPerformSegueWithIdentifier. If you want to do something special in response to the button click, use action-target and not a segue connected to the button.
I created a new project with your idea and I've got animation.
This is the action connected through IB with the next viewController and with identifier: #"getstartednext"
- (IBAction)go:(id)sender
{
}
Same code you have except sender is nil
- (void) nextClicked
{
dispatch_async(dispatch_get_main_queue(), ^{
[self performSegueWithIdentifier:#"getstartednext" sender:nil];
});
}
if sender != nil, (IBAction go:) then I'm calling nextClicked because returning NO
else the code is doing the segue because returning YES
- (BOOL) shouldPerformSegueWithIdentifier:(NSString *)identifier sender:(id)sender
{
if ([identifier isEqualToString:#"getstartednext"] && sender != nil)
{
[self nextClicked];
return NO;
}
return YES;
}
Works like a charm.
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.
I have a simple UIButton in a viewController.
- (IBAction)btnEnter:(id)sender {
..
..
}
Now I want to trigger the button press action programatically one of library functions (didFinishPickingmediaWithInfo) gets executed
- (void) imagePickerController: (UIImagePickerController*) reader didFinishPickingMediaWithInfo: (NSDictionary*) info
{
// Do Something
txtBoxAboveEnterButton = #"Data populated successfully";
[self btnEnter:nil];
[reader dismissModalViewControllerAnimated: YES];
}
The function is getting called and the text box above Enter button is getting populated with the dummy text but click is not getting triggered. Please help me out!
The method you are calling is btnEnter with no parameter. It doesn't look like you have that defined. Try passing a paramter like nil or self to it:
[self btnEnter:nil];