setDelegate to my custom view controller fall with unrecognized selector - ios

I have a view controller on the StoryBoard with my custom class. Here the code:
BGMDatePickerViewController.h
#import <UIKit/UIKit.h>
//declare a protocol with name
#protocol DatePickerViewControllerDelegate //declare a delegate so that this class can notify another class when a user selects a chart
//protocol methods
//- (void)userDataChangedWithUsername;
#end
//declare a class with inheritance
#interface BGMDatePickerViewController : UIViewController <UIPickerViewDelegate, UIPickerViewDataSource, UITextFieldDelegate>
//create a public property
#property (weak, nonatomic) id<DatePickerViewControllerDelegate> delegate; //property to store the delegate
#end
I would like to show this ViewController on another one with delegate. Here the code:
BGMChartViewController.h
#import <UIKit/UIKit.h>
#import "BGMDatePickerViewController.h"
//declare a class with inheritance
#interface BGMChartViewController : UIViewController <UIActionSheetDelegate, DatePickerViewControllerDelegate> //conforms UIActionSheetDelegate and my custom DatePickerViewControllerDelegate protocols
//create a public IB methods
- (IBAction)showDateEntryForm:(id)sender;
#end
BGMChartViewController.m
#import "BGMChartViewController.h"
#interface BGMChartViewController ()
//create a private properties
#property (strong, nonatomic) UIPopoverController *datePickerPopover;
#end
#implementation BGMChartViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:NO];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
}
- (IBAction)showDateEntryForm:(id)sender
{
DDLogVerbose(#"%s: has been started...", __FUNCTION__);
BGMDatePickerViewController *datePickerVC = [self.storyboard instantiateViewControllerWithIdentifier:#"dateEntryFormVC"];
datePickerVC.delegate = self; //HERE THE FALL!!!!!
self.datePickerPopover = [[UIPopoverController alloc] initWithContentViewController:datePickerVC];
//define the popover size
self.datePickerPopover.popoverContentSize = CGSizeMake(320.0, 400.0);
//let’s display it
[self.datePickerPopover presentPopoverFromRect:[(UIButton *)sender frame]
inView:self.view
permittedArrowDirections:UIPopoverArrowDirectionAny
animated:YES];
}
#end
On the line which I marked it just fall with:
-[BGMDatePickerViewController setDelegate:]: unrecognized selector sent to instance 0x78a3bcf0
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[BGMDatePickerViewController setDelegate:]: unrecognized selector sent to instance 0x78a3bcf0'
If I comment this problem line it's ok I see my custom view controller so that means that I am ok with instantiateViewControllerWithIdentifier tag...
I don't understand what do I do wrong?

Modify to the below line and check:-
#protocol DatePickerViewControllerDelegate<NSObject>

Related

Issue with passing a variable through prepareForSegue method

I am getting an error that I can't seem to solve:
*** Terminating app due to uncaught exception 'NSInvalidArgumentException',
reason: '-[UICollectionViewController setSearchString:]: unrecognized
selector sent to instance 0x7fcd4b655930'
The error comes when I call a prepareForSegue method:
- (void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
NSString *searchStringToPass = [[NSString alloc]initWithFormat:_inputField.text];
UINavigationController *navController = [segue destinationViewController];
ResultsCollectionViewController *rvc = (ResultsCollectionViewController *)([navController viewControllers][0]);
NSLog(#"Search String to Pass is: %#", searchStringToPass);
//[rvc setSearchString:searchStringToPass];
rvc.searchString = searchStringToPass;
//userViewController.user = [self.users objectInListAtIndex:[self.tableView indexPathForSelectedRow].row];
}
The ViewController that I am trying to get to is imbedded in a navigation controller. The code for it is:
#import "ResultsCollectionViewController.h"
#interface ResultsCollectionViewController ()
//#property(nonatomic, weak) IBOutlet UICollectionView *collectionView;
#property(strong, nonatomic) NSArray *flickrPhotos;
#end
#implementation ResultsCollectionViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
NSLog(#"search string is %#",_searchString);
}
-(void)getFlickrPhotosWithSearchString:(NSString*)searchString{
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
And the .h file is:
#import "BaseViewController.h"
#interface ResultsCollectionViewController : BaseViewController <UICollectionViewDataSource, UICollectionViewDelegateFlowLayout>
#property (strong, nonatomic) NSString *searchString;
#end
Anybody have any idea what the issue is? Many thanks in advance.
You report the following error message:
-[UICollectionViewController setSearchString:]: unrecognized selector sent to instance 0x7fcd4b655930
Note that the "unrecognized selector" in the error message is the setter accessor method for your searchString property, but the class referenced is the standard UICollectionVieController, not your custom class.
That suggests that you neglected to specify the base class for the destination scene in Interface Builder. The storyboard has therefore instantiated a standard UICollectionViewController rather than your custom class, and thus your searchString accessor methods are not found.

delegate respondsToSelector:selector not working

I saw a lot of this kind of questions and answers here, but couldn't find solution to my problem. I'm trying to send data from one view controller to another and use delegate. But don't know why my postDelegate doesn't responds to selector. Is something wrong with this code or what is the problem?
PostViewController.h file
#protocol GetDataDelegate <NSObject>
-(void)getPassedInfo:(NSString*)info;
#end
#interface PostViewController : UIViewController
#property (nonatomic, weak) id <GetDataDelegate> postDelegate;
#end;
PostViewController.m file
#import "PostViewController.h"
- (IBAction)postData:(id)sender {
if ([_postDelegate respondsToSelector:#selector(getPassedInfo:)]) {
[self.postDelegate getPassedInfo:#"data"];
NSLog(#"responds");
}
[self dismissViewControllerAnimated:YES completion:nil];
}
in second view controllers .h file
#import "PostViewController.h"
#interface MainViewController : UITableViewController <GetDataDelegate>
and in .m file
#implementation MainWindowTableViewController
- (void)viewDidLoad
{
[super viewDidLoad];
PostViewController * postController = [[PostViewController alloc]init];
postController.postDelegate = self;
}
and here is delegate method:
-(void)getPassedInfo:(NSString *)info{
NSLog(#"info is %#", info);
}
You need to make postController a property or an ivar. Currently it is a local variable in the viewDidLoad method which will be deallocated after viewDidLoad completes as #CodaFi said above.
#import "PostViewController.h"
#interface MainViewController : UITableViewController <GetDataDelegate>
#property (nonatomic, strong) PostViewController *postController;
#end
Then:
- (void)viewDidLoad
{
[super viewDidLoad];
self.postController = [[PostViewController alloc]init];
self.postController.postDelegate = self;
}

NSException with UIImagePickerController

I'm building my first IOS 7 iPad app in Xcode 5 - but I need some help with this issue.
I'm following this tutorial:
I don't quite understand what the writer means with:
"So open up testPickerViewController.h and we want to add in the following to the class reference."
UINavigationControllerDelegate, UIImagePickerControllerDelegate>
I got my view controller.h file here:
#import "ViewController.h"
#interface DetailViewController : ViewController <UINavigationControllerDelegate, UIImagePickerControllerDelegate>
{
UIImagePickerController *imgPicker;
IBOutlet UIImageView *customImage;
}
#property(nonatomic, retain)UIImagePickerController *imgPicker;
#end
my view controller.m file:
#import "DetailViewController.h"
#interface DetailViewController ()
#end
#implementation DetailViewController
#synthesize imgPicker, customImage;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
// Init the image picker
self.imgPicker = [[UIImagePickerController alloc]init];
self.imgPicker.allowsEditing = YES;
self.imgPicker.delegate = self;
self.imgPicker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
/*
#pragma mark - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
// Get the new view controller using [segue destinationViewController].
// Pass the selected object to the new view controller.
}
*/
- (IBAction)AddImage:(id)sender {
// Let the user add an image for the specific subject
[self presentModalViewController:self.imgPicker animated:YES];
}
-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingImage:(UIImage *)img editingInfo:(NSDictionary *)editingInfo {
customImage.image = img;
[[picker parentViewController] dismissModalViewControllerAnimated:YES];
}
#end
I ran the app without doing what I wrote at the top, which resulted in an NSException in the main.m file.
What am I doing wrong here?
Edit
main.m
#import <UIKit/UIKit.h>
#import "AppDelegate.h"
int main(int argc, char * argv[])
{
#autoreleasepool {
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
}
}
Edit
2014-05-17 14:56:47.509 myApp[1424:60b] * Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[ setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key image.'
Check the connection for the IBOutlet customImage in Interface Builder (IB) and make sure that the name of the referencing outlet and the UIImageView match. You can check by clicking on the Connection Inspector in IB (it's a little arrow inside of a circle).
In the tutorial that you posted a link to it shows the IBOutlet UIImageView declared as image. I'm assuming you changed the name of the IBOutlet and forgot to reconnect it. You can also check if the IBOutlet customImage is connected by checking if the dot beside the property declaration is filled or empty. Filled = connected and Empty = not connected.
Example of a property declaration for an IBOutlet:
#property (weak, nonatomic) IBOutlet UIImageView * customImage;
Also, <UINavigationControllerDelegate, UIImagePickerControllerDelegate> are protocols. By adding those lines to the #interface declaration you are, very simply, stating that, "I want my UIViewController to conform to the UINavigationControllerDelegate and the UIImagePickerControllerDelegate. I also want to implement my own code when certain events happen."

Need assistance regarding passing data from child to parent in UINavigationcontroller

In UINavigationController this is child controller
.h
#protocol childProtocol <NSObject>
-(void)childMethod:(NSArray*)params;
#end
#property (strong, nonatomic) id<childProtocol>childDelegate;
#property (weak, nonatomic) parentVC *pVC;
.m
if([self.childDelegate respondsToSelector:#selector(childMethod:)]) {
[self.childDelegate performSelector:#selector(childMethod:) withObject:self.arry];
}
This is my parent controller
.m
-(void)childMethod:(NSArray *)params {
// some work
}
...
childVC *cVC = [[childVC alloc]init];
cVC.pVC = self;
But childMethod: is not getting called so I searched on internet and got this post
UINavigationControllers: How to pass value to higher (parent?) controller in stack?
I tried to create a weak reference but dont know how to use to make delegate pass data from child to parent?
Try this. Check the sample project attached
ParentViewController.h
#import <UIKit/UIKit.h>
#interface ParentViewController : UIViewController
- (void)passData:(NSString *)strText;
#end
ParentViewController.m
- (IBAction)btnGoToSecondView:(id)sender {
ChildViewController *secondVC = [[ChildViewController alloc] initWithNibName:#"ChildViewController" bundle:nil];
secondVC.delegate = self;
[self presentViewController:secondVC animated:YES completion:nil];
}
- (void)passData:(NSString *)strText {
NSLog(#"Data Passed = %#",strText);
}
ChildViewController.h
#import <UIKit/UIKit.h>
#import "ParentViewController.h"
#class ParentViewController;
#interface ChildViewController : UIViewController
#property(nonatomic, assign) ParentViewController *delegate;
#end
ChildViewController.m
- (IBAction)btnPassDataBack:(id)sender {
if([self.delegate respondsToSelector:#selector(passData:)]) {
[self.delegate passData:#"Hello"];
}
[self dismissViewControllerAnimated:YES completion:nil];
}
Sample Project
This is child controller.h
#protocol childProtocol <NSObject>
-(void)childMethod:(NSArray*)params;
#end
#property (strong, nonatomic) id<childProtocol>childDelegate;
#property (weak, nonatomic) parentVC *pVC;
.m
if([self.childDelegate respondsToSelector:#selector(childMethod:)]) {
[self.childDelegate performSelector:#selector(childMethod:) withObject:self.arry];
}
This is my parent controller.h
#import <UIKit/UIKit.h>
#import "ChildController.h"
#interface perentController : UIViewController < childProtocol >
.m
- (void)childMethod:(NSArray *)params {
// some work
}
EDITED :
And Dont Forget to add childViewOBJ.childDelegate = self; at the time of create ChildViewController's object. such like,
childVC *cVC = [[childVC alloc]init];
cVC.childDelegate = self;
cVC.pVC = self;
[self presentModalViewController:cVC animated:YES];
For More information about How to create/use of Protocol.
First of all, you are not checking for the same selector as you declared in your protocol declaration so it won't respond to that. You declared the method childMethod: whereas you are checking if your childDelegate responds to myMethod: selector which does not so it won't go into the if condition.
Also the parent view controller is missing the implementation the method childMethod: in its .m. Implement that in your parent view controller or it will crash because of not finding the exact selector definition.
Since you are using a UINavigationController, the parent view controller won't be lost till the child view controller exist so the childDelegate property must not be strong unless you intend to hold onto your delegate in child view controller for some reason.

Unrecognized selector sent to instance using Storyboards

I'm using storyboard for an iOS application, my storyboard looks like this: http://d.pr/7yAY (droplr url)
The problem is when I click the login button, I send the username captured to the events table view controller. To do that I use prepareForSegue function, but apparently when I try to set the username in throws an exception.
My code is as follows:
ViewController.h
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController
- (IBAction) logintButton:(id)sender;
#property (weak, nonatomic) IBOutlet UITextField *username_tf; // textfield
#end
ViewController.m
#import "ViewController.h"
#import "EventsTableViewController.h"
#interface ViewController ()
#end
#implementation ViewController
#synthesize username_tf;
- (void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if([[segue identifier] isEqualToString:#"ToMainApp"])
{
EventsTableViewController * dest = (EventsTableViewController *)[segue destinationViewController];
NSString * username = [[NSString alloc] initWithFormat:#"%#", username_tf.text];
[dest setUsername:username];
}
}
- (IBAction) logintButton:(id)sender
{
//NSLog(#"Logint button pressed");
[self performSegueWithIdentifier:#"ToMainApp" sender:sender];
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)viewDidUnload
{
[self setUsername_tf:nil];
[super viewDidUnload];
// Release any retained subviews of the main view.
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}
EventsTableViewController.h
#import <UIKit/UIKit.h>
#interface EventsTableViewController : UITableViewController
{
NSString * username;
}
#property (nonatomic, retain) NSString * username;
#end
EventsTableViewController.m
#import "EventsTableViewController.h"
#interface EventsTableViewController ()
#end
#implementation EventsTableViewController
#synthesize username;
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
// Custom initialization
}
return self;
}
...
#end
The throwed exception is:
2012-03-15 14:19:27.304 StoryboardAssistance[30989:f803]
-[UINavigationController setUsername:]: unrecognized selector sent to instance 0x68abf60 2012-03-15 14:19:27.306
StoryboardAssistance[30989:f803] *** Terminating app due to uncaught
exception 'NSInvalidArgumentException', reason:
'-[UINavigationController setUsername:]: unrecognized selector sent to
instance 0x68abf60'
*** First throw call stack: (0x13c9022 0x155acd6 0x13cacbd 0x132fed0 0x132fcb2 0x28e6 0x43e4be 0xdb5ab 0x2974 0x13cae99 0x1614e 0x160e6
0xbcade 0xbcfa7 0xbc266 0x3b3c0 0x3b5e6 0x21dc4 0x15634 0x12b3ef5
0x139d195 0x1301ff2 0x13008da 0x12ffd84 0x12ffc9b 0x12b27d8 0x12b288a
0x13626 0x253d 0x24a5) terminate called throwing an exception(lldb)
Any suggestions?
Your segue's destination view controller is your Navigation Controller, not your Events Table View controller.
You can get the Events controller by accessing the Navigation controller's topViewController property.
Try this:
UINavigationController *navController = (UINavigationController*)[segue destinationViewController];
EventsTableViewController *eventsController = [navController topViewController];
NSString * username = [[NSString alloc] initWithFormat:#"%#", username_tf.text];
[eventsController setUsername:username];
Alternatively, try this:-
(It does the same as jonkroll's answer but in one line and removes the warning "Incompatible pointer types initializing 'ViewController *__strong' with an expression of type UIViewController *"
NameOfViewController *vc = (NameOfViewController *)[[segue destinationViewController] topViewController];
Another thing to verify is that you have properly assigned your destination ViewController as the proper class in Interface Builder. By default this will be UIViewController or UITableViewController etc. If you have a custom class with getters/setters, you need to remember to change the class in the Interface Builder to reflect accordingly, otherwise you will receive an invalid selector error message.

Resources