关于iOS16 以后屏幕旋转不得不说的事

由于笔者最近刚完成了一个强制屏幕横屏的需求 所以 顺便记录一下 实现过程中遇到 block点 也为广大的iOS开发者做一个笔记:

废话不多说直接上代码

 //适配iOS16.0的横竖屏方法
    public static func switchInterfaceWtihIos16(orientation: UIInterfaceOrientation , orientationMask: UIInterfaceOrientationMask) {
        if #available(iOS 16.0, *) {
            let array = UIApplication.shared.connectedScenes
            let geometryPreferencesIOS = UIWindowScene.GeometryPreferences.iOS(interfaceOrientations: orientationMask)
            if  let scene = array.first as? UIWindowScene {
                UIViewController.attemptRotationToDeviceOrientation()
                SystemManager.currentViewController()?.setNeedsUpdateOfSupportedInterfaceOrientations()
                scene.requestGeometryUpdate(geometryPreferencesIOS) { e in
                    log.info("iOS16 屏幕旋转失败:error \(e)")
                    scene.requestGeometryUpdate(geometryPreferencesIOS)
                }
            }

        } else {
            let resetOrientationTarget = NSNumber(value: UIInterfaceOrientation.unknown.rawValue)
            UIDevice.current.setValue(resetOrientationTarget, forKey: "orientation")
            let orientationTarget = NSNumber(value: orientation.rawValue)
            UIDevice.current.setValue(orientationTarget, forKey: "orientation")
        }
    }

值得一提的是 iOS16以后新增了GeometryPreferences 方法来旋转屏幕,所以设置横竖屏需要 使用的新的方法,并且入参为 UIInterfaceOrientationMask

调用上述方法以后 还要在需要实现横屏controller重写下面的方法和属性

    // 是否支持旋转
    open override var shouldAutorotate: Bool {
        return false
    }
    
    // 支持的方向
    open override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
        return .landscapeRight
    }
    // 首次展示的方向
    open override var preferredInterfaceOrientationForPresentation: UIInterfaceOrientation {
        return  .landscapeRight
    }
    @available(iOS 16.0, *)
    public override func setNeedsUpdateOfSupportedInterfaceOrientations() {
        let orientation = UIDevice.current.orientation
        if orientation == .landscapeLeft || orientation == .landscapeRight || orientation == .faceUp || orientation == .faceDown || isLandScreen {
            player.setfullScreen(isFull: true)
        } else {
            player.setfullScreen(isFull: false)
        }
    }

islandscreen 是我用来判断是否横屏的一个bool,直接复制可能会报错。大家复制后删除该判断再根据实际情况去修改就好

接下来着重说明一下 setNeedsUpdateOfSupportedInterfaceOrientations ,
这个是iOS16以后 的一个新方法,它的作用就是 每当屏幕旋转就会进入这个回调方法。当然你也可以主动调用,正如开篇方法中SystemManager.currentViewController()?.setNeedsUpdateOfSupportedInterfaceOrientations()
它的作用就是主动进入该方法中 。

然后通过查阅其他博主文章,如果想要屏幕旋转正常还需要加上UIViewController.attemptRotationToDeviceOrientation()
下面是官方描述 :

Summary

Attempts to rotate all windows to the orientation of the device.

所以老铁加上没毛病
这里总结一下

  1. 新建一个工具类或者拓展,加入代码块一 内容
  2. 在需要横竖屏的controller,复制 代码块二 内容
  3. 然后如果你的项目之前还没有做过横竖屏的适配你还得关于iOS16 以后屏幕旋转不得不说的事_第1张图片
    做截图相关配置。

你可能感兴趣的:(ios,swift,开发语言)