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

文章介绍了如何在iOS16中实现强制屏幕横屏,主要涉及UIApplication.shared.connectedScenes,UIWindowScene.GeometryPreferences以及UIViewController的相关方法。关键在于使用新的GeometryPreferences方法和setNeedsUpdateOfSupportedInterfaceOrientations方法来处理屏幕旋转。同时,需要在目标控制器中重写shouldAutorotate,supportedInterfaceOrientations和preferredInterfaceOrientationForPresentation方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

由于笔者最近刚完成了一个强制屏幕横屏的需求 所以 顺便记录一下 实现过程中遇到 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. 然后如果你的项目之前还没有做过横竖屏的适配你还得请添加图片描述
    做截图相关配置。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值