iOS 6:父模式的modalPresentationStyle在旋转后被忽略

时间:2021-07-14 11:09:30

With iPad with iOS6, we have this bug where a modal view controller will expand to full screen, even if it is told to be using "form sheet" presentation style. But, this happens only if there are two modals, a parent one and its child.

有了iPad和iOS6,我们就有了这个问题:模态视图控制器将扩展到全屏,即使它被告知使用“表单”表示样式。但是,只有当有两个情态动词时,才会发生这种情况,父情态动词和子情态动词。

So this is how the first modal is created and presented:

这就是第一个模态的创建和展示:

UINavigationController *navigationController = [[[UINavigationController alloc] initWithRootViewController:controller] autorelease];
navigationController.modalPresentationStyle = UIModalPresentationFormSheet;
[parentController presentModalViewController:navigationController animated:YES];
// parentController is my application's root controller

This is how the child modal is created and presented:

这是如何创建和呈现子模式的:

UINavigationController *navigationController = [[[UINavigationController alloc] initWithRootViewController:controller] autorelease];
navigationController.modalPresentationStyle = UIModalPresentationFormSheet;
[parentController presentModalViewController:navigationController animated:YES];
// parentController is the navigationController from above

So when rotating from landscape to portrait, the parent modal will expand to full screen and remain that way even if we rotate back to landscape.

所以当从横向旋转到纵向旋转时,父模态将会扩展到全屏并且保持这种状态即使我们回到横向旋转。

When we have the parent modal all by itself (no child modal), then it works as expected, which is that it remains in form sheet style.

当我们有父模式(没有子模式)时,它就像预期的那样工作,这就是它仍然是表单样式。

Note that this happens on iOS6 only (device and simulator) and doesn't happen on iOS 5 (simulator and reported to work by testers).

注意,这只在iOS6上发生(设备和模拟器),而在ios5上没有发生(模拟器和测试人员报告工作)。

So far, I have tried the following without success:

到目前为止,我尝试过以下方法,但没有成功:

  • setting wantsFullScreenLayout to NO
  • 设置wantsFullScreenLayout没有
  • forcing wantsFullScreenLayout to always return NO by overriding it
  • 强制wantsFullScreenLayout通过覆盖它来返回NO
  • Making certain my controllers inside the navigation controller also specify UIModalPresentationFormSheet
  • 确保导航控制器中的控制器也指定UIModalPresentationFormSheet
  • implementing preferredInterfaceOrientationForPresentation
  • 实现preferredInterfaceOrientationForPresentation
  • upgrade to iOS 6.0.1
  • 升级到iOS 6.0.1中

Thanks!

谢谢!


UPDATE: So, I adapted the response from the Apple Developer Forums (https://devforums.apple.com/message/748486#748486) so that it works with multiple nested modal.

更新:因此,我调整了苹果开发者论坛的响应(https://devforums.apple.com/message/748486#748486),以便它可以使用多个嵌套模式。

- (BOOL) needNestedModalHack {
    return [UIDevice currentDevice].systemVersion.floatValue >= 6;
}

- (void) willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
                                          duration:(NSTimeInterval)duration {

    // We are the top modal, make to sure that parent modals use our size
    if (self.needNestedModalHack && self.presentedViewController == nil && self.presentingViewController) {
        for (UIViewController* parent = self.presentingViewController;
             parent.presentingViewController;
             parent = parent.presentingViewController) {
            parent.view.superview.frame = parent.presentedViewController.view.superview.frame;
        }
    }

    [super willAnimateRotationToInterfaceOrientation:toInterfaceOrientation duration:duration];
}

- (void) willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
                                 duration:(NSTimeInterval)duration {
    // We are the top modal, make to sure that parent modals are hidden during transition
    if (self.needNestedModalHack && self.presentedViewController == nil && self.presentingViewController) {
        for (UIViewController* parent = self.presentingViewController;
             parent.presentingViewController;
             parent = parent.presentingViewController) {
            parent.view.superview.hidden = YES;
        }
    }

    [super willRotateToInterfaceOrientation:toInterfaceOrientation duration:duration];
}

- (void) didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation {
    // We are the top modal, make to sure that parent modals are shown after animation
    if (self.needNestedModalHack && self.presentedViewController == nil && self.presentingViewController) {
        for (UIViewController* parent = self.presentingViewController;
             parent.presentingViewController;
             parent = parent.presentingViewController) {
            parent.view.superview.hidden = NO;
        }
    }

    [super didRotateFromInterfaceOrientation:fromInterfaceOrientation];
}

3 个解决方案

#1


7  

Not sure if this should be considered as a bug and I'm curious what iOS 7 will bring, but the current workaround for this issue is to set modalPresentationStyle to UIModalPresentationCurrentContext for the child-viewController.

我不确定这是否应该被认为是一个bug,我很好奇ios7将带来什么,但是这个问题的当前解决方案是为child-viewController设置UIModalPresentationCurrentContext的modalPresentationStyle。

Set modalPresentationStyle = UIModalPresentationCurrentContext

This makes the child still beeing presented as FormSheet but prevents the parent from beeing resized to fullscreen on rotation.

这使得子进程仍然以表单形式显示,但是防止父进程在旋转时调整到全屏。

Dirk

德克

#2


0  

I can see 2 problems here.

这里有两个问题。

1) in iOS 6 the method presentModalViewController:animated: is deprecated, try using presentViewController:animated:completion: (despite this might not help, you still may want to do it)

1)在ios6中,方法presentModalViewController:animated: is deprecated,可以使用presentViewController:animated:completion:(尽管这可能没有帮助,但你还是想这么做)

2) In iOS 6 somehow appeared that container controllers (such as UINavigationController) don't resend the autorotate messages to their children. Try subclassing the UINavigationController and redefine the corresponding autorotation methods to be sent to all of the children. This might help.

2)在ios6中,容器控制器(比如UINavigationController)不会将自动发送的消息重新发送给他们的孩子。尝试对UINavigationController进行子类化,并重新定义要发送给所有孩子的相应的自动切换方法。这可能会有所帮助。

#3


-1  

You need to instanciate your navigation controller after your main view. So that you will be able to manage rotation in each view.

您需要在主视图之后实例化导航控制器。这样你就可以管理每个视图的旋转。

If your AppDelegate RootViewController is a navigation controller, you will not be able to manage rotation with native functions.

如果您的AppDelegate RootViewController是一个导航控制器,那么您将无法使用本机函数管理旋转。

#1


7  

Not sure if this should be considered as a bug and I'm curious what iOS 7 will bring, but the current workaround for this issue is to set modalPresentationStyle to UIModalPresentationCurrentContext for the child-viewController.

我不确定这是否应该被认为是一个bug,我很好奇ios7将带来什么,但是这个问题的当前解决方案是为child-viewController设置UIModalPresentationCurrentContext的modalPresentationStyle。

Set modalPresentationStyle = UIModalPresentationCurrentContext

This makes the child still beeing presented as FormSheet but prevents the parent from beeing resized to fullscreen on rotation.

这使得子进程仍然以表单形式显示,但是防止父进程在旋转时调整到全屏。

Dirk

德克

#2


0  

I can see 2 problems here.

这里有两个问题。

1) in iOS 6 the method presentModalViewController:animated: is deprecated, try using presentViewController:animated:completion: (despite this might not help, you still may want to do it)

1)在ios6中,方法presentModalViewController:animated: is deprecated,可以使用presentViewController:animated:completion:(尽管这可能没有帮助,但你还是想这么做)

2) In iOS 6 somehow appeared that container controllers (such as UINavigationController) don't resend the autorotate messages to their children. Try subclassing the UINavigationController and redefine the corresponding autorotation methods to be sent to all of the children. This might help.

2)在ios6中,容器控制器(比如UINavigationController)不会将自动发送的消息重新发送给他们的孩子。尝试对UINavigationController进行子类化,并重新定义要发送给所有孩子的相应的自动切换方法。这可能会有所帮助。

#3


-1  

You need to instanciate your navigation controller after your main view. So that you will be able to manage rotation in each view.

您需要在主视图之后实例化导航控制器。这样你就可以管理每个视图的旋转。

If your AppDelegate RootViewController is a navigation controller, you will not be able to manage rotation with native functions.

如果您的AppDelegate RootViewController是一个导航控制器,那么您将无法使用本机函数管理旋转。