prepareForSegue 和 tableView 的不同行为:didSelectRowAtIndexPath:

Posted

技术标签:

【中文标题】prepareForSegue 和 tableView 的不同行为:didSelectRowAtIndexPath:【英文标题】:Different behaviour of prepareForSegue and tableView: didSelectRowAtIndexPath: 【发布时间】:2012-06-08 05:21:00 【问题描述】:

我正在测试一个简单的场景,它有一个 UITableViewController,它的单元格连接到另一个 UIViewController。现在,在这个过程中,我需要向 UIViewController 传递一些信息,例如商品的名称和价格。我想测试使用 prepareForSegue 和 didSelectRowAtIndexPath: 来传递这两个数据点之间的区别。它似乎适用于 didSelectRowAtIndexPath: 但不适用于 prepareForSegue。做了一些调试后:

1-我想知道 prepareForSegue 是否在destinationViewController 上的任何IBOutlet 初始化之前发生,因此您无法有效地设置它们。所以 prepareForSegue 似乎更倾向于传递非 IBOutlet 属性。

2-如果我使用常规推送 segue,如何从 didSelectRowAtIndexPath: 方法访问“segue.destinationViewController”。

PS:在测试 prepareForSegue 时,我将 IB 中的 segue 设置为 push,而在测试 didSelectRowAtIndexPath: 时,我将 IB 中的 segue 设置为模态。

PS:所有与真实姓名的相似之处都是偶然的!

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

    if ([segue.identifier isEqualToString:@"itemDetailSegue"])
    
        NSIndexPath *indexPath=[self.tableView indexPathForSelectedRow];

        NSString *theItemName=[[self.itemsForSale objectAtIndex:indexPath.row]objectForKey:@"Name"];
        NSString *theItemPrice=[[self.itemsForSale objectAtIndex:indexPath.row]objectForKey:@"Price"];

        JuanDetailVC* juanDetailVC= (JuanDetailVC*) segue.destinationViewController;

        juanDetailVC.itemName.text=theItemName;
        juanDetailVC.itemPrice.text=theItemPrice;
    



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

    NSString *theItemName=[[self.itemsForSale objectAtIndex:indexPath.row]objectForKey:@"Name"];
    NSString *theItemPrice=[[self.itemsForSale objectAtIndex:indexPath.row]objectForKey:@"Price"];

    JuanDetailVC* juanDetailVC= (JuanDetailVC*) self.presentedViewController;

    juanDetailVC.itemName.text=theItemName;
    juanDetailVC.itemPrice.text=theItemPrice;


谢谢

【问题讨论】:

【参考方案1】:

你是对的,你不能在 prepareForSegue 中设置插座属性。您必须将属性传递给另一个属性,然后在目标视图控制器的 viewDidLoad 中设置插座的属性。例如:您不能设置标签的文本,您必须创建第二个属性(例如,NSString *labelText)并在 viewDidLoad 中设置标签的文本(self.label.text = self.labelText)。

您无权访问 tableView:didSelectRowAtIndexPath 中的目标视图控制器。您必须自己通过分配/初始化来创建实例。

【讨论】:

谢谢。第二点,如果我必须分配/初始化目标视图控制器的实例,我猜我也必须将它推送到导航控制器上。如果是这样的话,那么它就真的违背了故事板上推动 segue 的目的。那么这是否意味着一般来说,如果 1)您与模态视图控制器(就像我一样)或 2)您与弹出框 3)或可能在您所在的 iPad 上,您只使用 didSelectRowAtIndexPath 方法(而不是 prepareForSegue)访问详细视图控制器。换句话说,你的目的地真的是最后一个场景。谢谢 虽然我确信在某些情况下使用 didSelectRowAtIndexPath 更容易,但我现在想不出任何情况。我想我几乎总是使用 prepareForSegue。

以上是关于prepareForSegue 和 tableView 的不同行为:didSelectRowAtIndexPath:的主要内容,如果未能解决你的问题,请参考以下文章

prepareForSegue 和 popViewController 的兼容性

prepareForSegue 和 tableView 的不同行为:didSelectRowAtIndexPath:

使用 Storyboard 时对 prepareforsegue 和 presentModalViewController 的说明

Swift:prepareForSegue 和 instantiateViewController 之间的区别

你需要调用 super.prepareForSegue: 吗?

在 UISearchDisplayController 之后 prepareForSegue