我有UITableView
使用原型单元格。
单元格UIButton
使用UIViewController
显示Segue
(模态)。
我的问题是:如何将IndexPath
单元格传递给第二个视图控制器
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:@"showGamerDetail"]) {
//its not worked:
NSIndexPath *indexPath = [self._tableView indexPathForSelectedRow];
nDetailViewController *destinationViewController = segue.destinationViewController;
destinationViewController.selectedRowTitle = [gamers objectAtIndex:indexPath.row];
destinationViewController.indexPath = indexPath;
destinationViewController.delegate = self;
}
答案 0 :(得分:59)
暂时忘记你正在使用故事板,让我们尝试遵循最好的方法。
你有几个解决方案,但就我而言,其中只有一个是最优的: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
,但您需要计算所有其他信息。这是一种很酷的方法,但不是最好的方法。
// 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
是一种非常好的方法,可以传递所需的所有参数。实际上,您可能希望直接发回所需的信息,而无需在以后计算它们。
享受;)
答案 1 :(得分:1)
非常简单的解决方案,如果你想指向所选单元格的相同segue。
- (IBAction)buttonPressed:(id)sender {
CGPoint buttonPosition = [sender convertPoint:CGPointZero toView:self.tableView];
NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:buttonPosition];
[self tableView:self.tableView didSelectRowAtIndexPath:indexPath];
}
答案 2 :(得分:0)
首先创建一个全局int变量selecteIndex
;
在您的单元格中,为您的按钮标记添加类似于单元格的indexPath.row
值
E.g。 btn.tag = indexPath.row;
assing&amp;点击该按钮调用操作
[btn addTarget:self action:@selector(buttonClicked:) forControlEvents:UIControlEventTouchUpInside];
-(void)buttonClicked:(id)sender
{
UIButton *btn = (UIButton*)sender;
selectedIndex = btn.tag;
[self performSegueWithIdentifier:@"segueName" sender:self];
}
然后在你的视图结束时写下这个函数
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:@"segueName"]) {
viewController *dvc = (viewController *)[segue destinationViewController];
[dvc setSelected:selectedIndex];
};
}