respondsToSelector: not working for delegate
ios, ios5, objective-c, respondstoselector
Solution
For delegation to work, you need to set it up like this:
In your `FirstViewController.h` header file, make sure you are declaring that the second view controller is conforming to the delegating view controller's protocol:
@interface FirstViewController : UIViewController <SecondViewControllerDelegate>
You can see that the delegate goes within the `< >` symbols in the header file of a view controller. If there are required delegate methods within that protocol, Xcode will show warnings if you don't define them in the implementation file.
Then you have your delegate method defined in the `FirstViewController.m` file:
- (void)setSelection:(NSDictionary *)dict {
if (![dict isEqual:selection]) {
......
}
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:@"someSequeIdentifierHere"]) {
SecondViewController *sv = segue.destinationViewController;
sv.delegate = self;
}
}
You'll notice that instead of using `UIViewController` in the `prepareForSegue` method, you should just cast it to the actual view controller so you can set the properties on that. This way, you don't have to test if the view controller responds or not since it either has a `delegate` property defined or it doesn't (in which case, you need to add one).
To setup your original delegate protocol, you typically follow this format in your `SecondViewController.h` file:
@protocol SecondViewControllerDelegate <NSObject>
- (void)setSelection:(NSDictionary *)dict;
@optional
- (void)someOptionalDelegateMethodHere;
@end
@interface SecondViewController : UIViewController
@property (nonatomic, weak) id <SecondViewControllerDelegate>delegate;
@end
Delegates should almost always be weakly defined for ARC.
Then when you want to notify the delegate in `SecondViewController.m`
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
if ([self.delegate respondsToSelector:@selector(setSelection:)]) {
[self.delegate setSelection:item];
}
}
Since `delegate` is defined as a public property in the .h file, you can reference it either as `self.delegate` or `_delegate` but referencing it as `delegate` makes me think you incorrectly defined it as a private instance variable instead.
About the only time this type of a pattern won't respond to `respondsToSelector:` is when you don't correctly assign that `delegate` to your `FirstViewController`
Hope this helps!
Problem
I am new to iOS world and have run into an issue while trying to pass a value from a TableView back to the home controller. The scenario that I am working on is - Home Controller has a button - Click of button opens a list of items in the second UIViewController - User selects an item from list - Selected item is added to another list on Home Controller Really appreciate any pointers for this issue: This is how I am preparing for Segue on Home ``` - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { UIViewController *destination = segue.destinationViewController; if ([destination respondsToSelector:@selector(setDelegate:)]) { [destination setValue:self forKey:@"delegate"]; } } ``` SecondController has a delegate id, so I am assuming that delegate is set as "`respondsToSelector`" returns true for "setDelegate" Now, in SecondController when user selects an item I call `didSelectRowAtIndexPath` & `viewWillDisappear` methods to set the item and make the view disappear: ``` - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { POSAllItemsCell *cell = (POSAllItemsCell *) [tableView cellForRowAtIndexPath:indexPath]; item = [NSDictionary dictionaryWithObjectsAndKeys:cell.name, @"Name", cell.price, @"Price", cell.code, @"Code", nil]; [self dismissViewControllerAnimated:YES completion:NULL]; } - (void)viewWillDisappear:(BOOL)animated { [super viewWillDisappear:animated]; if ([delegate respondsToSelector:@selector(setSelection:)]) { [delegate setValue:item forKey:@"selection"]; } } ``` Now the problem here is that `respondsToSelector` for `setSelection` returns false even though I do have setSelection method in my HomeController: ``` - (void) setSelection:(NSDictionary *)dict { if (![dict isEqual:selection]) { ...... } } ``` Apologies in advance if my question in not clear or is not well formatted. BTW this is for iOS 5 with Xcode 4.2