supportedInterfaceOrientations无法正常工作

时间:2014-02-14 17:28:12

标签: ios orientation

我想要一些我的ViewControllers景观和一些肖像,所以这就是我所做的:

我启用了横向模式:

enter image description here

接下来,我将这些代码行添加到我想成为肖像的视图控制器中:

-(NSUInteger)supportedInterfaceOrientations
{
    return UIInterfaceOrientationPortrait;
}
-(BOOL)shouldAutorotate
{
    return NO;
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
    return UIInterfaceOrientationPortrait;
}

然而,当我旋转它们时,它们仍然会进入横向模式。我如何解决这个问题?

7 个答案:

答案 0 :(得分:21)

Apple为UINavigationController设计的方法是通过UINavigationControllerDelegate

通常我只是更新此委托以执行以下操作并将其委托给导航控制器堆栈中的顶部显示控制器:

#pragma mark - UINavigationControllerDelegate

- (NSUInteger)navigationControllerSupportedInterfaceOrientations:(UINavigationController *)navigationController
{
    return [navigationController.topViewController supportedInterfaceOrientations];
}

在我看来,UINavigationController应该默认为上述行为,但这是Apple提供的API:)

至于信息plist文件,我取消选中所有选项并在代码中处理所有选项,因为它在过去给我带来了问题,而我厌倦了处理它。

答案 1 :(得分:15)

我是这样做的。
创建一个UINavigationController父类。
在你内部UINavigationController(父)覆盖这些方法,如:

- (NSUInteger)supportedInterfaceOrientations
{
    if([self.topViewController respondsToSelector:@selector(supportedInterfaceOrientationsForThisContorller)])
    {
        return(NSInteger)[self.topViewController performSelector:@selector(supportedInterfaceOrientationsForThisContorller) withObject:nil];
    }
    return UIInterfaceOrientationPortrait;
}

- (BOOL)shouldAutorotate
{
    if([self.visibleViewController respondsToSelector:@selector(shouldAutorotateNow)])
    {
        BOOL autoRotate = (BOOL)[self.visibleViewController
                            performSelector:@selector(shouldAutorotateNow)
                            withObject:nil];
        return autoRotate;

    }
    return NO;
}

现在您的NavigationController应该是UINavigationContorller父

的子类

斯威夫特3:

在UINavigationController子类中执行此操作

override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
        get {
            return self.topViewController?.supportedInterfaceOrientations ?? .all
        }
    }

override var shouldAutorotate: Bool {
        return self.topViewController?.shouldAutorotate ?? false
    }

<强>更新 如果您不想继承,可以从Matt的answer获取:

首先:使viewController成为viewDidLoad

中navigationController的委托
self.navigationController?.delegate = self

然后声明UIViewController扩展以响应委托方法,如下所示:

extension UIViewController: UINavigationControllerDelegate {
    public func navigationControllerSupportedInterfaceOrientations(_ navigationController: UINavigationController) -> UIInterfaceOrientationMask {
        return navigationController.topViewController?.supportedInterfaceOrientations
    }
}

答案 2 :(得分:3)

Just for you all information, create a new project single view based Application, implement the should auto rotate delegate and the supportedInterface orientation in viewController add breakpoint in it.

The run (universal mode)

  1. on iphone simulator : execution stops at breakpoints
  2. on ipad Simulator : executions DOESN'T STOP (delegate methods are never called !!!!)
  3. on ipad device : ok

So don't waste too mush time on it like I juste Did, XCode 7.3 is BUGGED

答案 3 :(得分:0)

您可以在以下帖子中看到答案:

iOS 6 rotations: supportedInterfaceOrientations doesn´t work?

让我知道这是不是你的问题。

答案 4 :(得分:0)

在UINavigationController下,我正在实现UINavigationControllerDelegate和以下方法:

#pragma mark - From UINavigationControllerDelegate

-(UIInterfaceOrientationMask) navigationControllerSupportedInterfaceOrientations:(UINavigationController*)navigationController {
    return UIInterfaceOrientationMaskPortrait; // TODO: change to whatever you need to allow
}

答案 5 :(得分:0)

为简单起见,对于iPad,如果info.plist中的支持的界面方向(iPad)属性包括所有四个方向,并且 UIRequiresFullScreen 属性值为 NO ,iOS会将您的应用视为支持拆分视图。如果某个应用程序支持拆分视图功能,则至少通过上述方式,您不能禁止其旋转。


让我们深入研究细节。

首先,我们需要知道哪些因素会影响屏幕方向:

1。项目设置(info.plist)

我们可以在两个地方进行此设置:

  • 项目->目标->常规->设备方向

    screen orientation setting in project setting

  • 项目的info.plist

    screen orientation setting in info.plist

这两种方法相同,一个将自动同步另一个设置。 在info.plist文件中,支持的界面方向(iPad)属性用于iPad设置(为 Device 部分选择 iPad )和支持的界面方向属性适用于iPhone和Univeral(对于 Device 部分,选择 iPhone Universal 部分,这两个设置将始终为一样。)

2。以编程方式设置支持的屏幕方向

有两种方法可以在编码时配置支持的方向:

    supportedInterfaceOrientationsForWindow:中的
  • UIApplicationDelegate方法
  • supportedInterfaceOrientations中的
  • UIViewController方法

iOS系统将检查两种方法中定义的通用方向,并将这些通用方向用作视图控制器的支持方向。

3。在shouldAutorotate

中设置UIViewController属性

这是一个只读属性,用于控制视图控制器是否可旋转。您可以在视图控制器中覆盖该属性,甚至可以将该属性更改为可读写属性,以便您可以在应用运行时修改该属性。例如:

override public var shouldAutorotate: Bool {
    get {
        return self.shouldAutorotateVariable
    }
    set {
        self.shouldAutorotateVariable = newValue
    }
}

shouldAutorotateVariable是视图控制器中的私有属性。

iPhone

如果视图控制器的shouldAutorotate属性设置为false,iOS将忽略以下设置:

    supportedInterfaceOrientationsForWindow:中的
  • UIApplicationDelegate方法
  • supportedInterfaceOrientations中的
  • UIViewController方法

iOS将仅使用项目设置(info.plist)。

如果未覆盖shouldAutorotate属性或将其设置为true,则iOS将使用以下两种方法定义的通用方向:

    supportedInterfaceOrientationsForWindow:中的
  • UIApplicationDelegate方法
  • supportedInterfaceOrientations中的
  • UIViewController方法

如果未提供上述两种方法,iOS将使用项目设置(info.plist)。

iPad

iPad从iOS9开始支持拆分视图功能。有关分割视图的设置,请参见Slide Over and Split View Quick Start

为简单起见,如果info.plist中的支持的界面方向(iPad)属性包括所有四个方向,且 UIRequiresFullScreen 属性值为 NO ,iOS会将您的应用视为支持拆分视图。如果该应用支持拆分视图,则以下两个设置将被省略:

    supportedInterfaceOrientationsForWindow:中的
  • UIApplicationDelegate方法
  • supportedInterfaceOrientations中的
  • UIViewController方法

shouldAutorotate中的UIViewController属性也将被忽略。

也就是说,如果应用程序支持拆分视图功能,则至少通过上述方式,您不能禁止其旋转。

如果info.plist值中的支持的界面方向(iPad)属性未包含所有四个方向,或者 UIRequiresFullScreen 属性设置为 YES ,该应用将不支持拆分视图,并且屏幕方向控制逻辑与上述iPhone相同。

  

注意:对于项目设置(info.plist),最好直接在info.plist内设置以下三个属性:

     
      
  • 支持的界面方向(iPad)
  •   
  • 支持的界面方向
  •   
  • UIRequiresFullScreen
  •   
     

如果您尝试通过 Project-> Target-> General-> Device Orientation 进行设置,则会造成混淆:即使 Device 都设置为 Universe iPad 中的设置仍将生效。

答案 6 :(得分:0)

如果上述解决方案不起作用,那么如果您使用的是UITabBarController,则需要继承UITabBarController的子类,并需要重写以下方法

override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
    return .portrait
} 

我建议您对.all使用iPad扩展

 override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
     return UIDevice.current.userInterfaceIdiom == .phone ? [.portrait, .portraitUpsideDown] : .all

   }

希望对遇到相同问题的人有所帮助