viewDidAppear:在视图出现之前调用嵌套的UIViewController

时间:2014-07-04 14:32:26

标签: uiviewcontroller uikit uistoryboardsegue

上下文

我有一个视图控制器层次结构:

  1. 容器UIViewController A ,其中包含嵌入的子级UIPageViewController A B 之上覆盖各种内容,并通过导航和其他内容覆盖。
  2. 嵌入式UIPageViewController B
  3. B 显示的页面: C
  4. 实例化 A 时, B 会嵌入其中。我在 A 中覆盖prepareForSegue:sender会导致 C 被实例化并设置为 B 的当前页面:

    -(void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
    {
      if([[segue identifier] isEqualToString: @"EmbedPagesSegue"])
      {
        UIPageViewController *const pagesViewController = [segue destinationViewController];
        [pagesViewController setDataSource: self];
        [pagesViewController setDelegate: self];
        [self setPagesViewController: pagesViewController];
    
        UIViewController *const initialPage = [self initialDisplayedPage];
        [pagesViewController 
          setViewControllers: @[initialPage] 
          direction: UIPageViewControllerNavigationDirectionForward 
          animated: NO 
          completion:nil];
    
        // Point X.
        // Segue not yet started.
        // A is not on screen yet!
        // C has already been added to B
      }
    }
    

    问题

    C 会覆盖viewDidAppearAnimated:

    在显示初始页面时,在 C 的视图之前, C viewDidAppearAnimated:会在点X 处调用可以在屏幕上,因为 B 尚未添加到 A (segue刚刚设置)。

    这是一个问题,因为 C viewDidAppearAnimated:实现需要能够引用它出现的 A

    对于后续页面,嵌入segue已完成,因此 B 已添加到 A 在屏幕上。在这些情况下,viewDidAppearAnimated: C 的调用是合适的。

    或者,换句话说。

    viewDidAppearAnimated:实际上应该被称为viewDidAppearAnimatedInParentButTheParentMightNotHaveAppearedYet:

    问题

    1. 在此初始设置过程中, C 是否有一种干净的方法可以访问 A ?我可以做某种黑客,比如用performSelectorOnMainThread:withObject:waitUntilDone:推迟设置,但我宁愿不这样做。

    2. 我是否以错误的方式实现嵌入segue?

    3. 这只是一个糟糕的设计 - 在这种情况下,反而是什么?

    4. 还有其他建议吗?

1 个答案:

答案 0 :(得分:1)

通常,对视图或控制器层次结构的假设高于您所在的点是一个糟糕的设计。因此,通常不建议对父视图控制器或超级视图进行假设。在您的情况下,如果您需要从C访问A,请在C中创建公共API,您可以以某种形式(最有可能是weak)传递A,以便它可以自行配置。