如何在Swift中禁用和启用自动旋转?

13

在常规设置中,我允许纵向和左横屏、右横屏模式。我想关闭横屏模式。在视图控制器上,我编写了以下代码:

override func shouldAutorotate() -> Bool {

        return false

}

然而,自动旋转功能在忽略此函数的情况下工作。我该如何在Swift中禁用和启用自动旋转?IOS编程

5个回答

14

这可能是正确的代码,但不在正确的视图控制器中。例如,如果视图控制器嵌入在UINavigationController中,则导航控制器仍然可以旋转,导致视图控制器仍然旋转。这真的取决于您的具体情况。


嗨,Josh,是的,我将导航视图控制器嵌入到我的视图控制器中。那么我应该把这段代码放在哪里? - Yestay Muratov
子类化UINavigationController并将其放置在其中。基本上,您只需要检查顶部的视图控制器是否是要旋转的视图控制器即可。 - Josh Gafni
我不明白你说的“检查顶部的视图控制器”是什么意思。我在子类UINavigationController中放置了autorotate返回false。现在我的自动旋转不起作用了,这正是我想要的。之后,如果我的moviewplayer开始播放,我会将autorotate返回true。当我进入全屏模式时,旋转功能可以正常工作。但是当我退出全屏模式时,它就无法正常工作了。我不明白为什么会这样? - Yestay Muratov
我明白了。无论在视图控制器上使用should autorotate,它都不起作用。它只在导航控制器子类上起作用。由于某种原因,视频全屏不遵循uinavigationviewcontroller的自动旋转规则。 - Yestay Muratov

6

我曾经遇到同样的问题,现在我已经解决了。

按照以下步骤操作:

info --> 自定义 iOS 目标属性 --> 支持的设备方向,然后删除 ![删除 - 横屏 (Home按钮在左边), 横屏 (Home按钮在右边), 横屏 (Home按钮在上边)][1]

这将有助于解决您的问题。


4
您可以通过创建UINavigationController的子类,在其中覆盖shouldAutoRotate函数来实现此功能,然后...
  • return false for the viewControllers in which you want to disable autorotation
  • return true for the viewControllers in which you want autorotation

    import UIKit    
    
    class CustomNavigationController: UINavigationController {
    
    override func shouldAutorotate() -> Bool {
        if !viewControllers.isEmpty {
            // Check if this ViewController is the one you want to disable roration on
            if topViewController!.isKindOfClass(ViewController) {               //ViewController is the name of the topmost viewcontroller
    
                // If true return false to disable it
                return false
            }
        }
        // Else normal rotation enabled
        return true
       }
    }
    
如果你想在整个导航控制器中禁用自动旋转,去掉if条件并始终返回false。

0

在Josh Gafni和user3655266的回答基础上,这个概念也适用于视图控制器。

如果我们有一个UIViewController是另一个UIViewController在视图层次结构中的子级,覆盖子级的shouldAutorotate()为false可能仍然会旋转,因为它的父控制器可能仍然返回true。同样重要的是要知道,即使子VC正在显示,父级的shouldAutoRotate函数仍然会被调用。因此,控制应该在那里。

Swift 5

class ParentViewController:UIViewController{ 
    override func shouldAutorotate() -> Bool {
        // Return an array of ViewControllers that are children of the parent
        let childViewControllersArray = self.children
        if childViewControllersArray.count > 0 {
            // Assume childVC is the ViewController you are interested in NOT allowing to rotate
            let childVC = childViewControllersArray.first
            if childVC is ChildViewController {
            return false
            }
        }
        return true 
    }
}

同样的方法也可以用来限制特定的手机方向。

override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
        // This function is called on the parent's controller whenever the child of this parent is trying to rotate
        let childrenVCArray = self.children
        if childrenVCArray.count > 0 {
            // assuming the array of the first element is the current childVC
            let topMostVC = childrenVCArray[0]
            if topMostVC is ChildViewController {
                // Assuming only allowing landscape mode
                return .landscape
            }
        }
        // Return portrait otherwise
        return .portrait

    }

0

我不确定在2021年的Swift 5中shouldAutorotate()函数是否仍然可用。但是,我建议作为管理ViewController旋转的标准流程之一调用以下函数之一(请参见苹果开发者网站中的“处理视图旋转”部分)。例如,preferredInterfaceOrientationForPresentation


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