暂时忘记您正在使用情节提要,让我们尝试遵循最佳方法。
您有多种解决方案,但在我看来,只有其中一种是最佳的:delegation pattern。
首先,您应该扩展您的单元格,并在用户按下按钮时使用委托返回单元格。然后,您应该使用indexPathForCell 来获取indexPath。
让我们看看方法:
按按钮位置的单元格
- (void)buttonClicked:(id)sender
CGPoint buttonPosition = [sender convertPoint:CGPointZero
toView:self.tableView];
NSIndexPath *tappedIP = [self.tableView indexPathForRowAtPoint:buttonPosition];
// When necessary
// UITableViewCell *clickedCell = [self.tableView cellForRowAtIndexPath:tappedIP];
}
上述解决方案无疑是实施最快的,但从设计/架构的角度来看并不是最好的。此外,您会得到indexPath,但您需要计算所有其他信息。这是一个很酷的方法,但并不是最好的。
在按钮超级视图上按 while 循环
// ContactListViewController.m
- (IBAction)emailContact:(id)sender {
YMContact *contact = [self contactFromContactButton:sender];
// present composer with `contact`...
}
- (YMContact *)contactFromContactButton:(UIView *)contactButton {
UIView *aSuperview = [contactButton superview];
while (![aSuperview isKindOfClass:[UITableViewCell class]]) {
aSuperview = [aSuperview superview];
}
YMContactCell *cell = (id) aSuperview;
NSIndexPath *indexPath = [self.tableView indexPathForCell:cell];
return [[self fetchedResultsController] objectAtIndexPath:indexPath];
}
以这种方式获取单元格的性能不如前者,也不优雅。
按按钮标记的单元格
- (CustomCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
CustomCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell" forIndexPath:indexPath];
cell.theLabel.text = self.theData[indexPath.row];
cell.button.tag = indexPath.row;
[cell.button addTarget:self action:@selector(doSomething:) forControlEvents:UIControlEventTouchUpInside];
return cell;
}
-(void)doSomething:(UIButton *) sender {
NSLog(@"%@",self.theData[sender.tag]);
//sender.tag will be equal to indexPath.row
}
绝对没有。使用标签似乎是一个很酷的解决方案,但是控件的 标签可以用于其他原因,例如下一个响应者等。我不喜欢这种方法。
单元格设计模式
// YMContactCell.h
@protocol YMContactCellDelegate
- (void)contactCellEmailWasTapped:(YMContactCell*)cell;
@end
@interface YMContactCell
@property (weak, nonatomic) id<YMContactCellDelegate> delegate;
@end
// YMContactCell.m
- (IBAction)emailContact:(id)sender {
[self.delegate contactCellEmailWasTapped:self];
}
// ContactListViewController.m
- (void)contactCellEmailWasTapped:(YMContactCell*)cell;
NSIndexPath *indexPath = [self.tableView indexPathForCell:cell];
YMContact *contact = [[self fetchedResultsController] objectAtIndexPath:indexPath];
// present composer with `contact` ...
}
这是我最喜欢的解决方案。
使用delegation 或blocks 是一种非常好的方法,您可以传递所有需要的参数。事实上,您可能想直接发回所需的信息,而无需稍后计算。
享受;)