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