子视图控制器旋转方法未被调用

10

概述

我正在尝试将一个子视图控制器添加到一个父视图控制器中,并让父视图控制器通知子视图控制器旋转事件。然而,旋转消息没有被转发到子视图控制器(这是默认行为)。为什么默认行为没有发生?

环境: iOS 7, XCode 5, OSX 10.9

详细信息:

我正在实现一个自定义容器视图控制器,按照苹果文档中的说明进行操作:"创建自定义容器视图控制器"。我正试图建立一个简单的父子关系,以便转发旋转事件。整个层次结构与文档中的图14-1完全相同,如下所示:

ParentViewController --------> RootView
        |                       /   \
        |                      /     \
        ˅                     /       \
ChildViewController ---> ChildView     \ 
                                        \   
                                    OverLayView

我是通过使用父视图控制器中的文档清单4-1中的代码来实现这一点的 (unityViewController = childViewController, unityView = childView):

// In the ParentViewController    
// Called by the Application Delegate in application:didFinishLaunchingWithOptions:
- (void)addUnityViewController:(UIViewController *)unityViewController withUnityView:(UIView *)unityView
{
    [self addChildViewController:unityViewController]; // 1. Establish Child parent relationship

    unityView.frame = self.view.frame;                 // 2. Set the frame (explicitly or with constraints)
    [self.view addSubview:unityView];                  // 2.1 Add the subview AFTER you set the frame
    ... // add some view constraints here

    [self.view sendSubviewToBack:unityView];           // In the back, but not completely obstructed by any other views
    [unityViewController didMoveToParentViewController:self];// 3. Tell the child what happened
}

这段代码可以将child view成功显示为RootView的子视图,OverlayView添加了一些功能按钮。但是,当设备旋转时,父视图控制器可以成功旋转其视图,但未将旋转消息转发给子视图控制器(unityViewController),导致在rootView中显示不正确的childView(unityView)。根据"创建自定义容器视图控制器",这应该会自动发生:

自定义外观和旋转回调行为: 一旦将一个子视图添加到容器中,则容器会在需要转发消息时立即自动将旋转和外观回调转发给子视图控制器。

为确保这应该发生,我重写了以下方法:

// In the parent ViewController:
- (BOOL)shouldAutorotate
{
    return YES;
}

- (BOOL)shouldAutomaticallyForwardAppearanceMethods
{
    return YES;
}

- (BOOL)shouldAutomaticallyForwardRotationMethods
{
    return YES;
}
然而,willRotateToInterfaceOrientation:duration:didRotateFromInterfaceOrientation:方法在视图控制器(unityViewController)中从未被调用。我已经确认父级方法确实被调用,在这些方法中,我调用了super,但子级方法从未被调用。
问题: 为什么默认行为不会发生?我需要父级和子级均接收旋转消息以进行正确的显示。
注意:我知道我可以在父级中手动调用这些方法,但我不想手动调用它们并添加应该是默认行为的额外代码。
非常感谢你的帮助!

我在想你是否真的看到了视图的相反旋转:也就是说,父视图向一个方向旋转,而子视图则朝着另一个方向旋转。尝试在所有 shouldAutorotate 方法上返回 NO,看看是否有任何不同。如果确实有变化,则表示视图确实正在旋转,只是不是按照您预期的方式旋转。 - Anna Dickinson
2个回答

5
您可能需要在子视图上设置自动调整大小掩码:
[childView setAutoresizingMask: UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight];

这会确保视图在旋转过程中随其父视图一起调整大小。

5
为了使您的子视图控制器接收到转发方向回调,它必须是可见的。很可能您的子视图控制器不可见,因为它的视图还没有添加到视图层次结构中。
如果您将您的方法更改为以下内容,则应该开始看到旋转消息被调用:
- (void)addUnityViewController:(UIViewController *)unityViewController 
{
    [self addChildViewController:unityViewController];

    unityViewController.view.frame = self.view.bounds;
    [self.view addSubview:unityViewController.view];
    ... // add some view constraints here

    [self.view sendSubviewToBack:unityViewController.view];       
    [unityViewController didMoveToParentViewController:self];
}

更多信息请参考:在可见视图控制器中响应设备方向变化


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接