SwiftUI 以编程方式强制设备旋转

Bri*_*ski 5 orientation swiftui

我的应用程序具有根据设备设置的某些方向。对于 iPad,它设置为横向;对于 iPhone,它设置为纵向。这工作得很好,除了我想允许 iPhone 横向显示一个视图。我需要视图自动旋转到横向并在离开该视图后旋转回纵向。我有以下代码可以锁定该视图的方向,但必须手动来回旋转设备。有没有办法让设备自动旋转?

.onAppear {
            if(deviceType == .phone){
                UIDevice.current.setValue(UIInterfaceOrientation.portrait.rawValue, forKey: "orientation")
                AppDelegate.orientationLock = .landscape

            }
        }
.onDisappear {
            if(deviceType == .phone){
                AppDelegate.orientationLock = .portrait
            }
        }
Run Code Online (Sandbox Code Playgroud)

Kus*_*sar 10

在此输入图像描述

\n

View extension这可以使用更新视图方向来实现。让\xe2\x80\x99s 进行我们自己的扩展,它将rotateview给定的方向上来回移动。

\n
extension View {\n    @ViewBuilder\n    func forceRotation(orientation: UIInterfaceOrientationMask) -> some View {\n        if UIDevice.current.userInterfaceIdiom == .phone {\n            self.onAppear() {\n                AppDelegate.orientationLock = orientation\n            }\n            // Reset orientation to previous setting\n            let currentOrientation = AppDelegate.orientationLock\n            self.onDisappear() {\n                AppDelegate.orientationLock = currentOrientation\n            }\n        } else {\n            self\n        }\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n

在 AppDelegate 中添加:

\n
class AppDelegate: NSObject, UIApplicationDelegate {\n\n    static var orientationLock = UIInterfaceOrientationMask.portrait {\n        didSet {\n            if #available(iOS 16.0, *) {\n                UIApplication.shared.connectedScenes.forEach { scene in\n                    if let windowScene = scene as? UIWindowScene {\n                        windowScene.requestGeometryUpdate(.iOS(interfaceOrientations: orientationLock))\n                    }\n                }\n                UIViewController.attemptRotationToDeviceOrientation()\n            } else {\n                if orientationLock == .landscape {\n                    UIDevice.current.setValue(UIInterfaceOrientation.landscapeRight.rawValue, forKey: "orientation")\n                } else {\n                    UIDevice.current.setValue(UIInterfaceOrientation.portrait.rawValue, forKey: "orientation")\n                }\n            }\n        }\n    }\n    \n    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {\n        return true\n    }\n    \n    func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {\n        return AppDelegate.orientationLock\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n

这个小例子演示了如何使用此扩展:

\n
struct ContentView: View {\n        \n    var body: some View {\n        NavigationView {\n            List(Orientation.allCases, id: \\.self) { orientation in\n                       NavigationLink(orientation.title) {\n                           ZStack {\n                               Text(orientation.title)\n                           }\n                           .forceRotation(orientation: orientation.mask)  // << Update the required orientation here.. \n                       }\n                   }\n               }\n        }\n}\n\nenum Orientation: Int CaseIterable {\n    case landscapeLeft\n    case landscapeRight\n    \n    var title: String {\n        switch self {\n        case .landscapeLeft:\n            return "LandscapeLeft"\n        case .landscapeRight:\n            return "LandscapeRight"\n        }\n    }\n    \n    var mask: UIInterfaceOrientationMask {\n        switch self {\n        case .landscapeLeft:\n            return .landscapeLeft\n        case .landscapeRight:\n            return .landscapeRight\n        }\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n