我是 iOS 世界的新手,在尝试将值从 TableView 传回主 Controller 时遇到了问题。
我正在处理的场景是
- 家庭 Controller 有一个按钮
- 点击按钮打开第二个 UIViewController 中的项目列表
- 用户从列表中选择一个项目
- 所选项目已添加到家庭 Controller 上的另一个列表
非常感谢有关此问题的任何指示:
这就是我在家里准备 Segue 的方式
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
UIViewController *destination = segue.destinationViewController;
if ([destination respondsToSelector:@selector(setDelegate:)]) {
[destination setValue:self forKey:@"delegate"];
}
}
SecondController 有一个委托(delegate) ID,所以我假设委托(delegate)设置为“respondsToSelector
”,对于“setDelegate”返回 true
现在,在 SecondController 中,当用户选择一个项目时,我调用 didSelectRowAtIndexPath
和 viewWillDisappear
方法来设置项目并使 View 消失:
- (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"];
}
}
现在这里的问题是 respondsToSelector
for setSelection
返回 false 即使我的 HomeController 中确实有 setSelection 方法:
- (void) setSelection:(NSDictionary *)dict {
if (![dict isEqual:selection]) {
......
}
}
如果我的问题不清楚或格式不正确,请提前致歉。顺便说一句,这是针对带有 Xcode 4.2 的 iOS 5
最佳答案
要使委派工作,您需要这样设置:
在你的FirstViewController.h
头文件,确保你声明第二个 View Controller 符合委托(delegate) View Controller 的协议(protocol):
@interface FirstViewController : UIViewController <SecondViewControllerDelegate>
您可以看到委托(delegate)在 < >
内。 View Controller 头文件中的符号。如果该协议(protocol)中有必需的委托(delegate)方法,如果您没有在实现文件中定义它们,Xcode 将显示警告。
然后您在 FirstViewController.m
中定义了您的委托(delegate)方法文件:
- (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;
}
}
您会注意到,而不是使用 UIViewController
在prepareForSegue
方法,你应该将它转换为实际的 View Controller ,这样你就可以设置它的属性。这样,您就不必测试 View Controller 是否响应,因为它有一个 delegate
。属性已定义或未定义(在这种情况下,您需要添加一个)。
要设置您的原始委托(delegate)协议(protocol),您通常在 SecondViewController.h
中遵循此格式文件:
@protocol SecondViewControllerDelegate <NSObject>
- (void)setSelection:(NSDictionary *)dict;
@optional
- (void)someOptionalDelegateMethodHere;
@end
@interface SecondViewController : UIViewController
@property (nonatomic, weak) id <SecondViewControllerDelegate>delegate;
@end
对于 ARC,委托(delegate)几乎总是弱定义的。
然后当你想通知SecondViewController.m
中的代表时
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
if ([self.delegate respondsToSelector:@selector(setSelection:)]) {
[self.delegate setSelection:item];
}
}
自 delegate
在 .h 文件中定义为公共(public)属性,您可以将其引用为 self.delegate
或 _delegate
但将其引用为 delegate
让我觉得你错误地将它定义为私有(private)实例变量。
关于这种类型的模式唯一一次不会响应 respondsToSelector:
是当您没有正确分配 delegate
时给你的FirstViewController
希望这对您有所帮助!
关于ios - respondsToSelector:不为委托(delegate)工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16245808/