在一个模式视图控制器上强制 iOS 方向为横向

Posted

技术标签:

【中文标题】在一个模式视图控制器上强制 iOS 方向为横向【英文标题】:Force iOS orientation to landscape on one modal view controller 【发布时间】:2015-03-11 13:15:10 【问题描述】:

我有一个支持 iPad 和 iPhone 的通用应用程序。在 iPad 上,我支持所有方向,而在 iPhone 上,我只支持纵向。

我希望一个视图控制器(以模态方式显示)在 iPhone 上运行时以设备所在的任何方向显示。我看过许多建议使用 -(NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window 应用程序委托的教程和 SO 帖子方法,这在旋转模态视图控制器方面似乎工作得很好。但是,当我在横向模式下关闭模式视图时,整个应用程序仍然是横向的。

理想情况下,一旦模式视图被关闭,应用程序应立即返回纵向模式。

经过调查,在关闭视图控制器后似乎没有调用-(NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window 回调,我无法弄清楚原因。

我玩过示例应用程序here,当关闭视图控制器时会触发回调,我不知道为什么。我能看到的唯一区别是我的视图层次结构要复杂得多,而且我显示的是导航控制器而不是显式视图控制器,但我看不出这应该如何影响回调。

有什么想法可以解决这个问题吗?

谢谢

【问题讨论】:

【参考方案1】:

您可以尝试使用此方法(在应用商店构建中工作):

[[UIDevice currentDevice] performSelector:@selector(setOrientation:)
                               withObject:(__bridge id)((void*)UIInterfaceOrientationPortrait)];

【讨论】:

谢谢,与@Igor.Mursa 建议的解决方法一样有效。【参考方案2】:

在应用代理中:

  - (UIInterfaceOrientationMask)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window 

// Get topmost/visible view controller
    UIViewController *currentViewController = [self topViewController];

//Hire check your needed device ore other things you need
    if ( UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone )
     
     //device is iphone
         if ([currentViewController respondsToSelector:@selector(canRotate)]) 
         
            // Unlock landscape view orientations for this view controller
            return UIInterfaceOrientationMaskAll;
         
         return UIInterfaceOrientationMaskPortrait;
      
    else
    //device Ipad
    return UIInterfaceOrientationMaskAll;  



- (UIViewController*)topViewController 
return [self topViewControllerWithRootViewController:[UIApplication sharedApplication].keyWindow.rootViewController];


- (UIViewController*)topViewControllerWithRootViewController:(UIViewController*)rootViewController 
if ([rootViewController isKindOfClass:[UITabBarController class]]) 
    UITabBarController* tabBarController = (UITabBarController*)rootViewController;
    return [self topViewControllerWithRootViewController:tabBarController.selectedViewController];
 else if ([rootViewController isKindOfClass:[UINavigationController class]]) 
    UINavigationController* navigationController = (UINavigationController*)rootViewController;
    return [self topViewControllerWithRootViewController:navigationController.visibleViewController];
 else if (rootViewController.presentedViewController) 
    UIViewController* presentedViewController = rootViewController.presentedViewController;
    return [self topViewControllerWithRootViewController:presentedViewController];
 else 
    return rootViewController;


在需要旋转的视图中确保实现

  - (void)canRotate  

这将允许您仅旋转 iPhone 设备所需的视图。

我在旧的 *** 帖子的帮助下得到了这段代码,但我现在找不到它的链接

【讨论】:

感谢您的代码。我刚刚尝试过这个,但同样的问题存在。我可以旋转视图,但如果我在横向模式下关闭模式,应用程序不会恢复为纵向模式。由于某种原因,我的应用程序在关闭模式后似乎没有调用 supportedInterfaceOrientationsForWindow 方法。你有过这个问题吗? a 确实遇到过这种问题,当时我发现的唯一解决方案是在关闭视图之前以编程方式旋转视图,类似于 [self dismissViewControllerAnimated: YES completion:^ [self willAnimateRotationToInterfaceOrientation:UIDeviceOrientationPortrait duration:1];]; ,我不能 100% 确定这段代码是否会工作,我现在写了,我的情况 - 我正在展示一个导航控制器,我在展示之前正在旋转 谢谢。不幸的是,willAnimateRotationToInterfaceOrientation:duration:ios 8 中已被弃用,所以我不能使用它。当模式视图被关闭并手动调用应用程序委托方法时,我总是可以触发通知。不是最干净的方法。在使用这种方法之前,我会看看是否有任何其他建议或解决方法。 NSNumber *value = [NSNumber numberWithInt:UIInterfaceOrientationPortrait]; [[UIDevice currentDevice] setValue:value forKey:@"orientation"]; 试试这样设置怎么样

以上是关于在一个模式视图控制器上强制 iOS 方向为横向的主要内容,如果未能解决你的问题,请参考以下文章

iOS 6 中的模态视图控制器强制横向方向

IOS 6强制设备方向为横向

iOS:处理方向更改而不在视图控制器上启用横向模式

强制视图仅支持横向模式

在 iOS 9 中强制视图控制器方向

在 xcode 4.5 GM IOS 6 中将方向设置为横向模式