考虑一个带有两个子视图控制器(A和B)的容器视图控制器,两者都添加了addChildViewController:
。然后:
A.view
已添加到容器视图transitionFromViewController
来显示.B收到viewWillLayoutSubviews
并且对全世界都很好。willRotateToInterfaceOrientation:
等全部)。transitionFromViewController
来显示A. A未收到viewWillLayoutSubviews
因此布局已损坏。这是预期的行为吗?如果没有,我可能做错了什么?如果是,我应该怎么做才能在显示B时通知A旋转变化?
答案 0 :(得分: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];
}];
}
答案 1 :(得分:1)
加载并显示A
后,除非viewWillLayoutSubviews
的界限发生变化,否则不会再次调用A.view
。如果您需要每次在屏幕上显示视图时运行实施,您可以尝试将该代码移至viewWillAppear
。
答案 2 :(得分:1)
我能想到三种解决方案:
预先添加所有容器的视图控制器,并添加其视图,但隐藏除第一个之外的所有视图。然后在视图控制器之间转换的方法中,您不必再担心无数的包含相关方法(例如,您不需要willMoveToParentViewController
,addChildViewController
,removeFromParentViewController
,或didMoveToParentViewController
),而只是使用UIViewAnimationOptionShowHideTransitionViews
选项,它将显示或隐藏相应的视图。这样,所有控制器都会获得所有轮换通知。
第二个逻辑替代方案是预先仅创建第一个视图控制器。然后,当您想要转换到第二个视图控制器时,才会创建它(以及它的视图)。并确保您没有对原始控制器进行强有力的引用(例如,不仅是您自己的属性,还要确保removeFromParentViewController
等)。这将让它和它的观点被取消分配。因此,当您转换回来时,它将被重新创建。
如果您正在预先创建视图控制器,但让transitionFromViewController
添加和删除各自的视图到容器,那么我认为您可能必须调用相应的子轮换事件,如 View Controller Programming Guide中Customizing Appearance and Rotation Callback Behavior中所述。