在performSegue:withIdentifier:with popover style之后不调用prepareForSegue [英] prepareForSegue is not called after performSegue:withIdentifier: with popover style

查看:118
本文介绍了在performSegue:withIdentifier:with popover style之后不调用prepareForSegue的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个通用应用程序,我在那里为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上,我发生了变化Popover的segue标识符。
现在事情正在部分工作,执行了segue,但是没有调用prepareForSegue,因此目标视图控制器没有按原样设置。



我做错了什么?

解决方案

到目前为止我发现的是,任何不会突然出现的segue标识符是iOS的调用:




  • prepareForSegue(在源代码控制器上)

  • viewDidLoad(在目的地)控制器)



在popover segue中,调用顺序是:




  • viewDidLoad(在目标控制器上)

  • prepareForSegue(在源代码管理器上)



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



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



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

   - (void)prepareViewController {
//初始化逻辑...
}

并更改源控制器本身的prepareForSegue方法:

   - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
MyViewController * mvc =(MyViewController *)[segue destinationViewController] ;
//使用除popover之外的segue样式传递变量
//这首先调用viewDidLoad
mvc.myProp1 = @prop1;
mvc.myProp2 = @prop2;

// viewWillAppear尚未调用
//所以通过向控制器发送消息
//视图初始化为
[mvc prepareViewController];

}

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


I have a universal app, where I am sharing the same controller for a IPad and IPhone storyboard. I have put a UILongPressGestureRecognizer on a UITableView, that when a cell is pressed on iPhone it calls an action that perform a 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];
        }
    }
}

the segue is a detail view performed as a 'push'. The first thing you should notice is that the sender is an NSIndexPath, is the only way I found for passing the selected cell. Maybe there's a better solution. Everything works fine, in a sense that the segue is performed, and before the prepareForSegue is called too.

However it happens that on iPad, I have changed the segue identifier to Popover. Now things are working in part, the segue is performed, but prepareForSegue is not called and therefore the destination view controller is not set up as it should be.

What am I doing wrong ?

解决方案

What I have discovered so far, is that with any segue identifier that is not popover these are the invocations made by iOS:

  • prepareForSegue (on source controller)
  • viewDidLoad (on destination controller)

while in popover segue the invocation order is:

  • viewDidLoad (on destination controller)
  • prepareForSegue (on source controller)

just because I put all my logic in viewDidLoad, the controller was not properly initialized, and a crash happened. So this is not exactly true that prepareForSegue is not called, the truth is that I was getting an exception, and I wrongly mistaken as prepareForSegue not getting called.

I couldn't put everything in viewWillAppear because a call to CoreData had to be made and I didn't want to check if entities were ok each time the view display.

How did I solve this ? I created another method in destination controller

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

and changing the prepareForSegue method in source controller itself:

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

}

don't know if this is expected behavior with popover, anyway now things are working.

这篇关于在performSegue:withIdentifier:with popover style之后不调用prepareForSegue的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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