对 UITableView 使用 didSelectRowAtIndexPath 或 prepareForSegue 方法?

Posted

技术标签:

【中文标题】对 UITableView 使用 didSelectRowAtIndexPath 或 prepareForSegue 方法?【英文标题】:Use didSelectRowAtIndexPath or prepareForSegue method for UITableView? 【发布时间】:2011-12-29 03:47:48 【问题描述】:

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

【问题讨论】:

【参考方案1】:

如果您使用prepareForSegue:sender:,那么如果您稍后决定从表格视图之外的某些控件触发转场,您将无需进行太多更改。

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

在斯威夫特中:

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

【讨论】:

好的,你能举个例子说明如何通过基于indexPath传递一个对象来实现它。 self.view 不应该只是sender 吗?我什至无法让[self.view indexPathForSelectedRow] 工作,我不得不做[sender indexPathForSelectedRow]; 你会如何在 Swift 中做到这一点? @robmayoff 感谢您为 Swift 更新此内容。我做了一些细微的修改以反映最近的语言变化。希望这对其他人有所帮助 prepareFroSegue... 被调用时tableView.indexPathForSelectedRow() 包含正确的值很奇怪:tableView(_:didSelectrowAtIndexPath:) 直到稍后才被调用。【参考方案2】:

我这样做了,它成功了

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

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

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

【讨论】:

这没有意义。您应该使用 segue 或表视图委托。只需从 Cell 创建一个 segue,它就会自动执行与您所做的相同的事情,而无需编写代码。 如何在没有 didSelectRow 的情况下将 segue 分配给单元格?【参考方案3】:

当sender为UITableViewCell时,可以让UITableView查询cell的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
        
    

【讨论】:

【参考方案4】:

如果您的 tableView 属性在另一个类中并且您只有一个部分,那么您可以使用 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 

【讨论】:

【参考方案5】:

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

在斯威夫特中:

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
    

【讨论】:

【参考方案6】:

如果你使用prepareForSegue:,你可以检查谁是发件人并执行不同的代码

例如在 swift 中

override func prepareForSegue(segue: UiStoryboardSegue, sender: AnyObject?)

   var senderIsTableviewCell:Bool! = sender?.isKindOfClass(UITableViewCell)

   if senderIsTableviewCell
   
       //do something
   

【讨论】:

只要:如果让tableViewCell = sender as? UITableViewCell // 做点什么 .如果 sender 无法转换为 UITableViewCell,则不会执行“做某事”。

以上是关于对 UITableView 使用 didSelectRowAtIndexPath 或 prepareForSegue 方法?的主要内容,如果未能解决你的问题,请参考以下文章

在 WKInterface Table + Objective c 中重新加载数据

对 UITableView 使用 didSelectRowAtIndexPath 或 prepareForSegue 方法?

如何快速使用 CoreData 信息对 UITableView 进行排序?

使用 fetchedResultsController(核心数据)对部分进行排序以填充我的 UITableView

检测对 UITableView 空白区域的点击

如何使用 NSFetchedResultsController 按字母顺序对 UITableView 进行排序?