AnswerSoSelector: not working for delegate

I am new to the iOS world and ran into a problem while trying to transfer the value from TableView back to the home controller.

The script I'm working on

  • Home controller has a button
  • Click the button to open the list of items in the second UIViewController
  • The user selects an item from the list.
  • The selected item is added to another list on the Home Controller.

Carefully evaluate any pointers to this problem:

This is how I prepare 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 assume the delegate is set as " respondsToSelector " returns true for "setDelegate"

Now, in SecondController, when the user selects the item, I call the didSelectRowAtIndexPath and viewWillDisappear to set the item and the view disappears:

 - (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 is that respondsToSelector for setSelection returns false, even if I have the setSelection method in my HomeController:

 - (void) setSelection:(NSDictionary *)dict { if (![dict isEqual:selection]) { ...... } } 

Sorry in advance if my question is not clear or poorly formatted. BTW is for iOS 5 with Xcode 4.2

+4
source share
2 answers

To delegate work, you need to configure it as follows:

In your FirstViewController.h header file FirstViewController.h make sure you declare that the second view controller complies with the delegation manager protocol:

 @interface FirstViewController : UIViewController <SecondViewControllerDelegate> 

You can see that the delegate is included in the < > characters in the header file of the view controller. If this protocol has the necessary delegation methods, Xcode will display warnings if you do not 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 will notice that instead of using the UIViewController in the UIViewController method prepareForSegue you just have to refer it to the actual view controller so that you can set its properties. This way, you do not need to check if the view manager is responding or not, since it either has the delegate property or it is not (in this case you need to add it).

To configure the original delegate protocol, you usually follow this format in the 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 poorly 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 defined as a public property in the .h file, you can refer to it as self.delegate or _delegate , but referring to it as delegate makes me think that you incorrectly defined it as a private instance instead of a variable.

The only time that this type of template will not respond to respondsToSelector: is when you incorrectly assigned delegate to your FirstViewController

Hope this helps!

+10
source

Try the following:

 if ([destination respondsToSelector:@selector(setDelegate:)]) { [destination performSelector:@selector(setDelegate:) withObject:self]; } 
0
source

All Articles