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
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
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!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With