我有一个UITableViewCell
,其中包含一个按钮,当用户点击按钮或选择一个单元格时,我需要显示一个带有两个按钮的操作表。两个按钮都触发一个segue,我在prepareForSegue:
方法内传递数据(来自单元格)。它工作正常,但我想用协议来做,但不幸的是我无法正确实现它。
我现在就是这样做的:
@property (nonatomic, strong) PFUser *userObj;
-(UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
ContactsTableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:@"cell"];
PFUser *user = [self.dataSourceArray objectAtIndex:indexPath.row];
cell.usernm.text = user.username;
cell.userId.text = user.objectId;
cell.cellButton.tag = indexPath.row;
[cell.cellButton addTarget:self action:@selector(buttonTapped:) forControlEvents:UIControlEventTouchUpInside];
return cell;
}
- (void)buttonTapped:(id)sender {
UIButton *button = (UIButton *)sender;
self.userObj = [self.dataSourceArray objectAtIndex:button.tag];
[self setupActionSheet];
}
- (void) setupActionSheet {
AHKActionSheet *actionSheet = [[AHKActionSheet alloc] initWithTitle:NSLocalizedString(nil, nil)];
[actionSheet addButtonWithTitle:NSLocalizedString(@"Button 1", nil)
image:[UIImage imageNamed:@"1"]
type:AHKActionSheetButtonTypeDefault
handler:^(AHKActionSheet *as) {
[Utilz checkUser:self.userObj.objectId with:self.userObj.username];
}];
[actionSheet addButtonWithTitle:NSLocalizedString(@"Button 2", nil)
image:[UIImage imageNamed:@"2"]
type:AHKActionSheetButtonTypeDefault
handler:^(AHKActionSheet *as) {
[self performSegueWithIdentifier:@"presentNextView" sender:self];
}];
[actionSheet show];
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([[segue identifier] isEqualToString:@"presentNextView"]) {
if ([[segue destinationViewController] isKindOfClass:[ViewControllerTwo class]]) {
ViewControllerTwo *dataToPass = [segue destinationViewController];
dataToPass.usrStr = self.usrObj.username;
dataToPass.objStr = self.usrObj.objectId;
}
}
}
以下是我尝试使用协议进行的操作:
首先,我创建了一个名为DataPassProtocol.h
的协议。
然后我在ContactsTableViewCell.h
添加了一个ENUM并导入了DataPassProtocol.h
typedef NS_ENUM(NSInteger, MyUserCellAction) {
MyUserCellActionCheckUser,
MyUserCellActionPerformSegue
};
我还将这些变量添加到ContactsTableViewCell.h
@property (weak) id <DataPassProtocol> delegate;
@property (nonatomic, strong) PFUser *user;
- (IBAction)buttonTapped:(id)sender;
在ContactsTableViewCell.m
我添加了这些方法
- (void)setUser:(PFUser *)user {
_user = user;
// setup UI
self.usernmLabel.text = _user.username;
self.userIdLabel.text = _user.objectId;
}
- (IBAction)buttonTapped:(id)sender {
// cell handles its button being tapped
NSLog(@"Button tapped");
if ([self.delegate respondsToSelector:@selector(myUser:didPerformAction:)]) {
[self.delegate myUser:self.user didPerformAction:MyUserCellActionCheckUser];
}
if ([self.delegate respondsToSelector:@selector(myUser:didPerformAction:)]) {
[self.delegate myUser:self.user didPerformAction:MyUserCellActionPerformSegue];
}
}
我在第二个if语句中遇到错误。
不允许将'NSInteger'(又名'int')隐式转换为'id' 与ARC
我真的不知道为什么会这样。
另一个错误:
an Expected a type in this method implementation of the protocol file.
- (void)myUser:(PFUser *)user didPerformAction:(MyUserCellAction)action;
此外在MyDelegateViewController
我收到了此警告:
执行中的冲突参数类型 'myUser:didPerformAction:':'_ _ rstrong id'vs'MyUserCellAction'(又名 'enum MyUserCellAction')
我把它放在我的桌面视图所在的VC中。
- (void)myUser:(PFUser *)user didPerformAction:(MyUserCellAction)action {
if (action == MyUserCellActionCheckUser) {
// do what we want
} else if (action == MyUserCellActionPerformSegue) {
// do the other thing we want
}
}
这是协议实现:
@protocol DataPassProtocol <NSObject>
@optional
- (void)myUser:(PFUser *)user didPerformAction:(MyUserCellAction)action;
我怎么能让它起作用?这是我的第一个协议,所以我真的不知道我该怎么做。
答案 0 :(得分:0)
根据您所描述的内容,您似乎尚未将MyUserCellAction枚举的定义导入您的协议。如果你想使用枚举,我会将MyUserCellAction枚举的定义移动到协议中(无论如何你的单元都在导入协议,因此可以访问这个定义)。我也会把协议称为更具描述性的东西,比如CellActioning或ContactsTableViewCellDelegate。
另一方面,我建议不要传递枚举,而是使用两种方法performSegueActionForUser:(PFUser *)user
performCheckActionForUser:(PFUser *)user
或者其他方法。
将enum或boolean标志传递给方法调用以确定该方法应该执行的操作是Control Coupling的一个示例,如果遵循正确的软件工程原则,则不鼓励这样做。
http://en.wikipedia.org/wiki/Coupling_%28computer_programming%29