3

考虑一个带有两个子视图控制器(A 和 B)的容器视图控制器,它们都添加了addChildViewController:. 然后:

  1. A.view被添加到容器视图中
  2. B 通过transitionFromViewController从 A 到 B 做来显示。B 收到viewWillLayoutSubviews并且世界上一切都很好。
  3. 设备在显示 B 时旋转。只有 B 接收旋转调用(willRotateToInterfaceOrientation:等)。
  4. 通过transitionFromViewController从 B 到 A 显示 A。A 没有收到viewWillLayoutSubviews,因此布局被破坏。

这是预期的行为吗?如果没有,我可能做错了什么?如果是,我应该怎么做才能在显示 B 时通知 A 旋转变化?

4

3 回答 3

5

只要你打电话addChildViewController:,你现在就是一个视图控制器容器实现者。这意味着您必须比标准的演示电话(如presentViewController... 这包括处理您添加为子项的控制器的视图框架,正如您的问题所暗示的那样,您可能已经预料到了。

例如,要实现一个超级基本的示例容器,它只显示每个孩子全屏,你可以做这样的事情。

-(void)swapChildVCFrom:(UIViewController *)from to:(UIViewController *)to{
    [self addChildViewController:to];
    [from willMoveToParentViewController:nil];

    // Adjust the new child view controller's view's frame
    // For example here just set it to fill the parent view
    to.view.frame = self.view.bounds;

    [self transitionFromViewController:from
                      toViewController:to
                              duration:1.0
                               options:UIViewAnimationOptionTransitionFlipFromLeft
                            animations:nil
                            completion:^(BOOL b){
                                [to didMoveToParentViewController:self];
                                [from.view removeFromSuperview];
                                [from removeFromParentViewController];
                            }];
}
于 2012-11-17T23:20:34.320 回答
1

我能想到的解决方案有以下三种:

  1. 预先添加所有容器的视图控制器,并添加它们的视图,但隐藏除第一个之外的所有视图。然后在视图控制器之间转换的方法中,您不必再担心无数与包含相关的方法(例如,您不需要willMoveToParentViewControlleraddChildViewControllerremoveFromParentViewControllerdidMoveToParentViewController),而只需使用UIViewAnimationOptionShowHideTransitionViews将显示或隐藏的选项适当的意见。这样,所有控制器都会收到所有轮换通知。

  2. 第二种合乎逻辑的选择是只预先创建第一个视图控制器。然后,当您想要转换到第二个视图控制器时,您才会创建它(以及它的视图)。并确保您不保留对原始控制器的强引用(例如,不仅是您自己的属性,而且还要确保removeFromParentViewController,等等)。这将让它和它的视图被释放。因此,当您转换回来时,它将被重新创建。

  3. 如果您要预先创建视图控制器,但transitionFromViewController要向容器中添加和删除它们各自的视图,那么我认为您可能必须调用适当的子旋转事件,就像在自定义外观和旋转回调行为中讨论的那样在视图控制器编程指南中。

于 2012-11-17T19:33:54.367 回答
1

A加载并显示后,除非边界发生变化viewWillLayoutSubviews,否则不会再次调用。A.view如果您需要在每次视图出现在屏幕上时运行您的实现,您可以尝试将该代码移动到viewWillAppear.

于 2012-11-17T19:26:13.483 回答