呈现视图控制器会触发UIApplicationDidChangeStatusBarOrientationNotification

时间:2015-06-05 00:17:49

标签: ios objective-c iphone ios7 ios8

我有一个支持iPad和iPhone的通用应用程序,在iPhone上它支持UIInterfaceOrientationPortraitUpsideDown

当我在iPhone上运行应用程序时,将设备旋转到UIInterfaceOrientationPortraitUpsideDown,然后以模态方式呈现这样的视图控制器:

UIViewController* vc = [[UIViewController alloc] initWithNibName:nil bundle:nil];
UINavigationController* navigationController = [[UINavigationController alloc]
                                              initWithRootViewController:vc];
navigationController.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
[self presentViewController:navigationController animated:YES completion:nil];

非常意外地,这会触发UIApplicationDidChangeStatusBarOrientationNotification

好的,也许这是因为模态视图控制器不支持倒置纵向方向。让我们创建UIViewController的自定义子类来覆盖supportedInterfaceOrientations

- (NSUInteger) supportedInterfaceOrientations
{
  return UIInterfaceOrientationMaskAll;
}

但没有区别,呈现自定义VC仍会触发通知。我还注意到iPad上的通知,仅在iPhone上触发。最后,iOS 8和iOS 7中的行为是相同的(特别是我在iOS 8.1和iOS 7.1上进行测试,但我怀疑这有什么不同)。

问题:提交模式VC时发送此通知是否正常?为什么它只发生在UIInterfaceOrientationPortraitUpsideDown,而不是普通肖像或两个横向方向中的任何一个?为什么它只发生在iPhone而不是iPad?

注意:我可以根据要求提供更完整,最小化的运行示例。

1 个答案:

答案 0 :(得分:1)

问题确实是模态呈现的视图控制器不支持UIInterfaceOrientationPortraitUpsideDown。我添加supportedInterfaceOrientations覆盖的想法是正确的,但我错误的地方是我将覆盖添加到UIViewController - 的自定义子类中,但这是提供的视图控制器!

正如我的代码段所示,呈现的视图控制器是UINavigationController实例。因此,我的问题的一个正确解决方案是创建UINavigationController的子类并将supportedInterfaceOrientations添加到该子类。

另一个正确的,但在我看来,比子类更优雅的解决方案是使用UINavigationControllerDelegate协议。

第1步:修改我的问题中的代码段:

UIViewController* vc = [[UIViewController alloc] initWithNibName:nil bundle:nil];
UINavigationController* navigationController = [[UINavigationController alloc]
                                              initWithRootViewController:vc];
navigationController.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
// --- THE NEXT LINE IS NEW ---
navigationController.delegate = self;
[self presentViewController:navigationController animated:YES completion:nil];

步骤2:确保包含呈现代码的类(=上面的代码段)采用UINavigationControllerDelegate协议。

步骤3(是的, 步骤3):将此协议方法添加到新指定的委托类中:

- (NSUInteger) navigationControllerSupportedInterfaceOrientations:(UINavigationController*)navigationController
{
  return UIInterfaceOrientationMaskAll;
}

如果您有许多展示视图控制器的地方,您可能希望拥有一些采用UINavigationControllerDelegate的共享对象,但这是您应用程序设计的一部分。