Swift横竖屏切换、自动旋转屏幕、手动旋转屏幕、锁定当前屏幕禁止转屏、横竖屏页面跳转过度、横竖屏UI适配

demo放在了文末

1.AppDelegate中增加屏幕方向属性UIInterfaceOrientationMask

class AppDelegate: UIResponder, UIApplicationDelegate {
    var orientationLock = UIInterfaceOrientationMask.allButUpsideDown // 默认支持方向   
    func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {
        return self.orientationLock
    }
}

2.UIWindowScene增加转屏扩展方法

extension UIWindowScene {
    func setInterfaceOrientation(_ orientation: UIInterfaceOrientation) {
        let orientationMask: UIInterfaceOrientationMask
        switch orientation {
        case .portrait:
            orientationMask = .portrait
        case .landscapeLeft:
            orientationMask = .landscapeLeft
        case .landscapeRight:
            orientationMask = .landscapeRight
        default:
            orientationMask = .allButUpsideDown
        }
        
        if #available(iOS 16.0, *) {
            let geometryPreferences = UIWindowScene.GeometryPreferences.iOS(interfaceOrientations: orientationMask)
            self.requestGeometryUpdate(geometryPreferences) { error in
                print("Error requesting geometry update: \(error.localizedDescription)")
            }
        } else {
            UIDevice.current.setValue(orientation.rawValue, forKey: "orientation")
            UINavigationController.attemptRotationToDeviceOrientation()
        }
    }
}

3.转屏

if let windowScene = view.window?.windowScene {
           if windowScene.interfaceOrientation.isPortrait {
                windowScene.setInterfaceOrientation(.landscapeRight)
                // 恢复为支持所有方向
                DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
                    let appDelegate = UIApplication.shared.delegate as! AppDelegate
                    appDelegate.orientationLock = .all
                }
            } else {
                windowScene.setInterfaceOrientation(.portrait)
                // 恢复为支持所有方向
                DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
                    let appDelegate = UIApplication.shared.delegate as! AppDelegate
                    appDelegate.orientationLock = .all
                }
            }
        }

4.监听屏幕转动变化刷新横竖屏UI

/// 横竖屏旋转监听
    override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
        super.traitCollectionDidChange(previousTraitCollection)
        if traitCollection.verticalSizeClass != previousTraitCollection?.verticalSizeClass {
            // 横竖屏UI适配
            if UIDevice.current.orientation.isCurrentScreenPortrait() {
                button?.frame = CGRect(x: 10, y: 250, width: UIScreen.main.bounds.width-20, height: 50)
            } else {
                button?.frame = CGRect(x: 80, y: 250, width: UIScreen.main.bounds.width-160, height: 50)
            }
        }
    }

5.锁定屏幕

if let appDelegate = UIApplication.shared.delegate as? AppDelegate {
            appDelegate.orientationLock = interfaceOrientationMask(from: UIDevice.current.orientation)   
        }
        UIViewController.attemptRotationToDeviceOrientation()

6.解锁

if let appDelegate = UIApplication.shared.delegate as? AppDelegate {
            appDelegate.orientationLock = .all
        }
        DispatchQueue.main.asyncAfter(deadline: DispatchTime.now()+0.5, execute: {
            UIViewController.attemptRotationToDeviceOrientation()
        })

demo

posted @ 2024-07-19 11:29  zk1947  阅读(246)  评论(0编辑  收藏  举报