【问题标题】:Preventing rotation in a specific view controller in iOS 11防止在 iOS 11 中的特定视图控制器中旋转
【发布时间】:2019-04-15 22:33:37
【问题描述】:

我试图防止在特定 VC 中旋转(锁定为纵向) 嵌入在导航控制器中。

我目前正在这样做:

到 UINavigationController

extension UINavigationController {
    public override func supportedInterfaceOrientations() -> Int {
        return visibleViewController.supportedInterfaceOrientations()
    }
}

在我的 VC 中:

class ViewController: UIViewController {
    override func supportedInterfaceOrientations() -> Int {
        return Int(UIInterfaceOrientationMask.Landscape.rawValue)
    }
}

但是,当我们转到另一个支持横向和纵向的 VC(嵌入在另一个导航控制器中)时,我遇到了问题。假设,用户在新屏幕中旋转到横向。并单击返回以返回原始屏幕。该应用程序现在以横向显示,而不是在其 supportedInterfaceOrientations 覆盖中定义的纵向显示。如何防止这种错误行为?

我在 iOS 11 中读到,我们应该使用 viewWillTransition(to:with:) 来处理旋转(以及锁定)。在 UIViewController 文档中

“从 iOS 8 开始,所有与旋转相关的方法都已弃用。反而, 旋转被视为视图控制器大小的变化 视图,因此使用 viewWillTransition(to:with:) 报告 方法。当界面方向改变时,UIKit 会调用 窗口的根视图控制器上的方法。然后那个视图控制器 通知其子视图控制器,传播消息 整个视图控制器层次结构。”

你能指导一下如何实现吗?

【问题讨论】:

    标签: ios swift


    【解决方案1】:

    您可以使用我一直在使用的这个很酷的实用程序。

    struct AppUtility {
    
        static func lockOrientation(_ orientation: UIInterfaceOrientationMask) {
    
            if let delegate = UIApplication.shared.delegate as? AppDelegate {
                delegate.orientationLock = orientation
            }
        }   
    
        /// OPTIONAL Added method to adjust lock and rotate to the desired orientation
        static func lockOrientation(_ orientation: UIInterfaceOrientationMask, andRotateTo rotateOrientation:UIInterfaceOrientation) {
    
            self.lockOrientation(orientation)
    
            UIDevice.current.setValue(rotateOrientation.rawValue, forKey: "orientation")
        }
    }
    

    您还可以旋转屏幕,同时将其锁定到该方向。我希望这会有所帮助!

    【讨论】:

    • UIDevice.current.setValue(rotateOrientation.rawValue, forKey: "orientation") 未记录在案,并且可能不安全地使用 API。我在网上找到的大多数解决方案都使用了它。你知道实现它的推荐方法是什么吗?
    • 嗯。我不知道。但是我有多个项目使用了这个功能,从来没有被拒绝过。
    • 是的,但是设备的设置方向看起来很奇怪。感觉这些只是为了获取方向等
    • 使用或不使用。由你决定。仅仅因为您使用 setValue forKey,并不意味着它被禁止使用并且您的项目会被拒绝。
    【解决方案2】:

    您可以使用supportedInterfaceOrientationsFor

    在你的AppDelegate中定义这个

    var restrictRotation = Bool()

    func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {
        if restrictRotation {
            return .portrait
        }
        else {
            return .all
        }
    }
    

    将以下代码放入您的ViewController

    func restrictRotation(_ restriction: Bool) {
        let appDelegate = UIApplication.shared.delegate as? AppDelegate
        appDelegate?.restrictRotation = restriction
    }
    

    像这样在ViewController ViewwillAppear 中调用上述函数。

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        self.restrictRotation(true) // TRUE MEANS ONLY PORTRAIT MODE
                  //OR
        self.restrictRotation(false) // FALSE MEANS ROTATE IN ALL DIRECTIONS
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多