在performSegue:withIdentifier:with popover style之后不调用prepareForSegue

时间:2012-01-12 16:02:57

标签: objective-c ipad xcode4 storyboard uipopovercontroller

我有一个通用应用程序,我在那里为IPad和IPhone故事板共享相同的控制器。 我在UITableView上放了一个UILongPressGestureRecognizer,当在iPhone上按下一个单元格时,它调用一个执行segue的动作:

-(IBAction)showDetail:(id)sender {
    UILongPressGestureRecognizer *gesture = (UILongPressGestureRecognizer*)sender;
    if (gesture.state == UIGestureRecognizerStateBegan) {
        CGPoint p = [gesture locationInView:self.theTableView];

        NSIndexPath *indexPath = [self.theTableView indexPathForRowAtPoint:p];
        if (indexPath != nil) {
            [self performSegueWithIdentifier:SEGUE_DETAIL sender:indexPath];
        }
    }
}

segue是作为“推送”执行的详细视图。您应该注意的第一件事是发件人是NSIndexPath,是我找到的传递所选单元格的唯一方法。也许有更好的解决方案。 一切都运行良好,从某种意义上说,执行segue,并且在调用prepareForSegue之前。

然而,在iPad上,我已经将segue标识符更改为Popover。 现在事情正在部分工作,执行segue,但是没有调用prepareForSegue,因此目标视图控制器没有按原样设置。

我做错了什么?

2 个答案:

答案 0 :(得分:20)

到目前为止我发现的是,对于任何不是popover的segue标识符,这些是iOS发出的调用:

  • prepareForSegue(在源代码管理器上)
  • viewDidLoad(在目标控制器上)

在popover segue中,调用顺序为:

  • viewDidLoad(在目标控制器上)
  • prepareForSegue(在源代码管理器上)

因为我将所有逻辑都放在viewDidLoad中,控制器没有正确初始化,并且发生了崩溃。所以这并不完全正确,因为没有调用prepareForSegue,事实是我得到了一个异常,而且我错误地认为,因为prepareForSegue没有被调用。

我无法将所有内容放在viewWillAppear中,因为必须进行对CoreData的调用,并且我不想在每次显示视图时检查实体是否正常。

我是如何解决这个问题的?我在目标控制器中创建了另一种方法

-(void)prepareViewController {
  // initialization logic...
}

并在源代码管理器本身中更改prepareForSegue方法:

-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
  MyViewController *mvc = (MyViewController*)[segue destinationViewController];
  // passing variable 
  // with segue style other than popover this called first than viewDidLoad
  mvc.myProp1=@"prop1"; 
  mvc.myProp2=@"prop2";

  // viewWillAppear is not yet called
  // so by sending message to controller
  // the view is initialized
  [mvc prepareViewController];

}

不知道这是否是popover的预期行为,无论如何现在事情正在发挥作用。

答案 1 :(得分:1)

我注意到Xcode的Master-Detail模板(iPhone)的样板代码使用以下模式来配置VC的详细视图:

  1. 细节VC的setter(用于属性)被覆盖以调用configureView方法(configureView将更新视图中的所有控件,例如标签等)。
  2. 详细信息VC的viewDidLoad方法也调用configureView方法
  3. 有一天,当我试图在我的电影应用中重复使用细节VC时,我没有遵循这种模式,这给了我带来麻烦。

    我对弹出窗口没有多少经验;但是,如果上面的模式与弹出窗口中显示的详细VC一起使用,那么当您在prepareForSegue方法中设置详细VC的属性时,是否不会配置详细VC的视图?