不再好奇 發表於 2022-9-23 11:48:00

配置iOS 16 屏幕旋转适配实例详解

<div id="navCategory"><h5 class="catalogue">目录</h5><ul class="first_class_ul"><li>正文</li><li>一. AppDelegate 配置</li><ul class="second_class_ul"><li>定义一个 bool 类型的变量</li></ul><li>二. 适配 iOS16 旋转屏幕</li><ul class="second_class_ul"></ul><li>三. 强制旋转屏幕</li><ul class="second_class_ul"></ul><li>四. 自动旋转</li><ul class="second_class_ul"></ul></ul></div><p class="maodian"></p><h2>正文</h2>
<p>我们公司的 app 只支持竖屏, 只有在视频播放的时候才可以<code>横屏</code>, 所以这就需要我们强制去旋转屏幕. 我想一般的 app 大概都会有这种需求.</p>
<p>最近随着 <code>iOS16</code> 的更新, 线上的 app 在 <code>iOS16</code> 系统上不管用了, 原因就是苹果从 <code>iOS16</code> 开始, 更改了屏幕旋转的机制, 以后都要用 <code>UIWindowScence</code> 这个 API 类. 所以我们的 App 就只能根据版本去做适配, 新的要支持, 老的也要兼容.</p>
<p>在这里, 我就直接上干货, 只展示重要代码, 就不写 <code>demo</code>, 没什么技术含量, 做为一个日常记录分享而已.</p>
<p>重点提示</p>
<p><code>Xcode 14.0</code><code>MacOS 12.5</code>手机 <code>iOS15.1</code> 和 <code>iOS16</code></p>
<p class="maodian"></p><h2>一. AppDelegate 配置</h2>
<p class="maodian"></p><h3>定义一个 bool 类型的变量</h3>
<p>全局控制否是横屏代理方法根据这个变量来返回是 <code>竖屏</code> 还是 <code>横屏</code>, <code>iOS16</code> 及以上可以做到根据屏幕方向适配横屏, 我们公司要求不高, 所以我们是强制右横屏, 这一点是不太友好, 这不是重点.</p>
<ul><li>这一步 <code>Swift</code> 和 <code>ObjC</code> 没什么区别, 只是语法不同, 所以就只提供了 <code>Swift</code> 代码.</li></ul>
<div class="jb51code"><pre class="brush:cpp;">@main
class AppDelegate: UIResponder, UIApplicationDelegate {
    var window: UIWindow?
    // 定义一个 bool 类型的变量
    var isFullScreen: Bool = false
    func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -&gt; UIInterfaceOrientationMask {
      if isFullScreen {
            if #available(iOS 16.0, *) {
                // 16 及以上可以做到根据屏幕方向适配横屏
                return .landscape
            } else {
                // 16 以下不方便做, 所以我们是强制 右横屏
                return .landscapeRight
            }
      }
      return .portrait
    }
}
</pre></div>
<p class="maodian"></p><h2>二. 适配 iOS16 旋转屏幕</h2>
<p>在原来基础上添加适配 <code>iOS16</code> 的代码 在 <code>VC</code> 中点击横屏按钮时进行强制屏幕旋转, 这里强调一下, 播放器的横屏按钮操作最好是回调到当前 VC 中去操作, <code>setNeedsUpdateOfSupportedInterfaceOrientations()</code> 这个方法是 VC 的对象方法, 这里同样<code>Swift</code> 和 <code>ObjC</code> 没什么区别, 只是语法不同.</p>
<div class="jb51code"><pre class="brush:cpp;">func switchOrientation(isFullScreen: Bool) {
      let kAppdelegate = UIApplication.shared.delegate as? AppDelegate
      kAppdelegate?.isFullScreen = isFullScreen
      // 设置屏幕为横屏
      if #available(iOS 16.0, *) {
            setNeedsUpdateOfSupportedInterfaceOrientations()
            guard let scence = UIApplication.shared.connectedScenes.first as? UIWindowScene else {
                return
            }
            let orientation: UIInterfaceOrientationMask = isFullScreen ? .landscape : .portrait
            let geometryPreferencesIOS = UIWindowScene.GeometryPreferences.iOS(interfaceOrientations: orientation)
            scence.requestGeometryUpdate(geometryPreferencesIOS) { error in
                print("强制\(isFullScreen ? "横屏" : "竖屏" )错误: \(error)")
            }
      } else {
            let oriention: UIDeviceOrientation = isFullScreen ? .landscapeRight : .portrait
            UIDevice.current.setValue(oriention.rawValue, forKey: "orientation")
            UIViewController.attemptRotationToDeviceOrientation()
      }
      // 更新 横竖屏对应的 UI
      // ...
    }
</pre></div>
<p class="maodian"></p><h2>三. 强制旋转屏幕</h2>
<p>在播放器横竖屏切换按钮的回调方法中调用 旋转屏幕方法即可, 不管手机有没有打开自动旋转, 都可以实现屏幕方向切换.</p>
<div class="jb51code"><pre class="brush:cpp;">    // 播放器 - 全屏按钮切换回调
    func playerViewRotateScreen(isFull: Bool) {
      switchOrientation(isFullScreen: isFull)
    }
</pre></div>
<p class="maodian"></p><h2>四. 自动旋转</h2>
<p>手机需要打开自动旋转开关, 注册屏幕旋转通知, 监听屏幕旋转时的方向. 方法不只一种, 但是我就用下面这个.</p>
<ul><li>一定要注意下面这两个方法, 否则有可能通知不生效, 一个开启一个关闭.<ul><li>UIDevice.current.beginGeneratingDeviceOrientationNotifications()</li><li>UIDevice.current.endGeneratingDeviceOrientationNotifications()</li></ul></li><li><code>注意:</code> 我这里做的是 16 以下只支持<code>右横屏</code>, 16 不需要获取设备方向, 因此可以支持 <code>左/右</code>横屏. 这也是 <code>AppDelegate</code> 中区分版本的原因.</li></ul>
<p>友情提示 :</p>
<p>最好是把<code>侧滑返回手势</code>给禁掉. 否则横屏侧滑返回就出问题了, 当然也可以做的更精细些, 横屏时禁止. 我做验证就简单些.</p>
<div class="jb51code"><pre class="brush:cpp;">    override func viewDidAppear(_ animated: Bool) {
      super.viewDidAppear(animated)
      UIDevice.current.beginGeneratingDeviceOrientationNotifications()
      NotificationCenter.default.addObserver(self, selector: #selector(screenChangedOrientation(_:)), name: UIDevice.orientationDidChangeNotification, object: nil)
      navigationController?.interactivePopGestureRecognizer?.isEnabled = false
    }
    override func viewWillDisappear(_ animated: Bool) {
      super.viewWillDisappear(animated)
      navigationController?.interactivePopGestureRecognizer?.isEnabled = true
    }
    override func viewDidDisappear(_ animated: Bool) {
      super.viewDidDisappear(animated)
      NotificationCenter.default.removeObserver(self)
      UIDevice.current.endGeneratingDeviceOrientationNotifications()
    }
    // 横竖屏监听
    @objc private func screenChangedOrientation(_ notification: Notification) {
      let info = notification.userInfo
      guard let animated = info?["UIDeviceOrientationRotateAnimatedUserInfoKey"] as? Int, animated == 1 else {
            return
      }
      let orientation = UIDevice.current.orientation
      if orientation == UIDeviceOrientation.landscapeLeft || orientation == UIDeviceOrientation.landscapeRight {
            // 横屏
            videoView.changeScreenOrientation(isFull: true)
      } else if orientation == UIDeviceOrientation.portrait {
            // 竖屏
            videoView.changeScreenOrientation(isFull: false)
      }
    }</pre></div>
<p>以上就是配置iOS 16 屏幕旋转适配实例详解的详细内容,更多关于iOS 16 屏幕旋转适配的资料请关注琼殿技术社区其它相关文章!</p>
                           
                            <div class="art_xg">
                              <b>您可能感兴趣的文章:</b><ul><li>iOS15适配小结</li><li>iOS文本的多语言适配以及实践指南</li><li>如何实现axios的自定义适配器adapter</li><li>iOS WKWebView适配实战篇</li><li>iOS13适配深色模式(Dark Mode)的实现</li><li>iOS13适配三指撤销和文案限长实例详解</li></ul>
                            </div>

                        </div>
                        <!--endmain-->
頁: [1]
查看完整版本: 配置iOS 16 屏幕旋转适配实例详解