如何使用Seque在tableView中找到点击按钮的indexPath [英] How to find indexPath for tapped button in tableView Using Seque

查看:31
本文介绍了如何使用Seque在tableView中找到点击按钮的indexPath的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个使用原型单元格的 UITableView.

I have a UITableView using prototype cell.

单元格有一个 UIButton,它使用 Segue 显示一个 UIViewController (Modal).

The cells have a UIButton that show a UIViewController (Modal) using Segue.

我的问题是:如何将单元格的 IndexPath 传递给第二个视图控制器

My question is : How can i pass IndexPath of cell to second view controller

- (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;
    }

推荐答案

暂时忘记您正在使用故事板,让我们尝试遵循最佳方法.

Forget for a moment that you are using storyboard, and let's try to follow the best approach.

您有多种解决方案,但在我看来,只有其中一种是最佳的:委托模式.

You have several solution, but for my opinion, just 1 of these is optimal: delegation pattern.

首先,您应该扩展您的单元格,并在用户按下按钮时使用委托返回单元格.然后,您应该使用 indexPathForCell 来获取 indexPath.

First, you should extend your cell, and using delegation to return the cell when the user press the button. Then, you should use indexPathForCell to get the 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 但您需要计算所有其他信息.这是一个很酷的方法,但不会说是最好的.

the solution above is certainly the most rapid to implement, but it is not the best from the point of view of the design/architecture. Moreover you get the indexPath but you need then to calculate every other info. This is a cool method, but would say not the best.

// 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];
}

这种方式获取cell性能不如前者,也不优雅.

Get the cell in this way is less performant of the former, and it is not elegant as well.

- (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
}

绝对没有.使用标签似乎是一个很酷的解决方案,但控件的标签可用于其他原因,例如下一个响应者等.我不喜欢这种方法.

Absolutely no. Use the tag could seem a cool solution, but the tag of a control can be used for other reasons, like the next responder etc. I don't like this approach.

// 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` ...
}

这是我最喜欢的解决方案.使用 delegationblocks 是一个非常好的方法,并且你可以传递你想要的所有参数.事实上,您可能希望直接发回所需的信息,而无需稍后计算.

This is my favourite solution. Using delegation or blocks is a really nice approach and you can pass all the parameters you want. In fact you could want to send back directly the needed info, without having to calculate them later.

享受;)

这篇关于如何使用Seque在tableView中找到点击按钮的indexPath的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆