对UITableView使用didSelectRowAtIndexPath或prepareForSegue方法?


101

我正在使用情节提要,并且有一个UITableView。我有一个segue设置,可将表格从表推送到详细信息VC。但是我应该使用哪种方法来处理呢?我必须将几个对象传递到详细信息视图。但是我使用didSelectRowAtIndex还是-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender

Answers:


199

如果使用prepareForSegue:sender:,则以后再决定从表视图外部的某些控件触发segue时,将没有太多更改。

prepareForSegue:sender:消息被发送到当前视图控制器,所以我建议是这样的:

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    // Assume self.view is the table view
    NSIndexPath *path = [self.tableView indexPathForSelectedRow];
    DetailObject *detail = [self detailForIndexPath:path];
    [segue.destinationViewController setDetail:detail];
}

在Swift中:

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
    let path = self.tableView.indexPathForSelectedRow()!
    segue.destinationViewController.detail = self.detailForIndexPath(path)
}

1
好的,您可以举一个如何通过基于indexPath的对象来实现它的示例。
乔恩

4
self.view应该只是在sender这里吗?我什[self.view indexPathForSelectedRow]至无法上班,我不得不做[sender indexPathForSelectedRow];
ladookie 2011年

您将如何在Swift中做到这一点?
用户

@robmayoff感谢您为Swift进行更新。我做了一些细微的修改以反映最近的语言更改。希望这对其他人有所帮助
Zack Shapiro 2015年

调用tableView.indexPathForSelectedRow()时包含正确的值很奇怪prepareFroSegue...tableView(_:didSelectrowAtIndexPath:)直到稍后才调用。
Nicolas Miari

5

我做到了,它奏效了

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{

    NSLog(@"Row Selected = %i",indexPath.row);

    [self performSegueWithIdentifier:@"testID" sender:self.view];    
}

11
那没有道理。您应该使用segue或表视图委托。只需从Cell中创建一个序列,它便会自动执行与编写代码相同的操作。
Yariv Nissim 2013年

3
在没有didSelectRow的情况下,如何为单元分配序列?
Morkrom 2013年

3

当发件人是UITableViewCell时,您可以要求UITableView查询单元格的indexPath。

    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
        if let cell = sender as? UITableViewCell {
            let indexPath = self.tableView.indexPathForCell(cell)!
            assert(segue.destinationViewController.isKindOfClass(DetailViewController))
            let detailViewController = segue.destinationViewController as! DetailViewController
            detailViewController.item = self.items[indexPath.row] // like this
        }
    }

1

如果tableView属性在另一个类中,并且只有一个section,则可以使用该tag属性存储单元格的行,例如:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

     UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell"];

     cell.tag = indexPath.row;

     return cell;
}

然后,您可以访问它,因为sender标记中的行是与该单元格相同的单元格:

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {

    MyDestinationViewController *destinationViewController = segue.destinationViewController;
    destinationViewController.myProperty = [tableViewElementsArray objectAtIndex:[sender tag]]; // sender will be your cell 
}

1

self.tableView.indexPathForSelectedRow返回选定的单元格,但不返回发送方单元格,例如,未选择发送方单元格(辅助操作),或者在多个选择情况下。最好的方法是获取segue发送者的indexPath:

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    __auto_type itemViewController = (id<ItemViewController>)segue.destinationViewController;
    itemViewController.senderIndexPath = [self.tableView indexPathForCell:sender];
}

在Swift中:

protocol ItemViewController {
    var senderIndexPath : IndexPath? { get set }
    var selectedIndexPaths : [IndexPath]? { get set }
}

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if  let cell = sender as? UITableViewCell,
        var itemViewController = segue.destination as? ItemViewController {
        itemViewController.senderIndexPath = tableView.indexPath(for: cell)
        itemViewController.selectedIndexPaths = tableView.indexPathsForSelectedRows
    }
}

0

如果使用prepareForSegue:,则可以检查谁是发件人并执行其他代码

例如迅速

override func prepareForSegue(segue: UiStoryboardSegue, sender: AnyObject?)
{
   var senderIsTableviewCell:Bool! = sender?.isKindOfClass(UITableViewCell)

   if senderIsTableviewCell
   {
       //do something
   }
}

2
只是做:如果让tableViewCell = sender为?UITableViewCell {//做某事}。如果无法将发件人强制转换为UITableViewCell,则“执行某些操作”将不会执行。
mbeaty
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.