繁体   English   中英

SwiftUI 除了一个视图之外的所有视图强制肖像

[英]SwiftUI Force Portrait On All Except One View

我有一个 SwiftUI 项目。 对于除其中一个视图之外的所有视图,我想允许纵向模式并且仅允许纵向模式。 对于只有一个视图,我想同时允许纵向和横向。 Swift 上有一些资源,但我在 SwiftUI 上找不到。

有没有人找到一种方法来完成这个?

我不得不做类似的事情。 这是我们的方法。

我们将项目方向设置为仅支持纵向模式。

然后在您的AppDelegate添加一个用于方向的实例变量并符合supportedInterfaceOrientationsFor委托方法。

static var orientationLock = UIInterfaceOrientationMask.portrait

func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {
    return AppDelegate.orientationLock
}

然后,当您要呈现横向视图时,请执行以下操作:

AppDelegate.orientationLock = UIInterfaceOrientationMask.landscapeLeft
UIDevice.current.setValue(UIInterfaceOrientation.landscapeLeft.rawValue, forKey: "orientation")
UIViewController.attemptRotationToDeviceOrientation()

而在解雇时,

AppDelegate.orientationLock = UIInterfaceOrientationMask.portrait
UIDevice.current.setValue(UIInterfaceOrientation.portrait.rawValue, forKey: "orientation")
UIViewController.attemptRotationToDeviceOrientation()

希望这可以帮助!

对上述答案的一些调整:

在 AppDelegate 中作为乔纳森上面的回答:

static var orientationLock = 
UIInterfaceOrientationMask.portrait

func application(_ application: UIApplication, 
supportedInterfaceOrientationsFor window: 
UIWindow?) -> UIInterfaceOrientationMask {
return AppDelegate.orientationLock
}

然后在“destinationView”中 - 风景:

import SwiftUI

struct DestinationView: View {

var body: some View {
    Group {

        Text("Hello")

    }.onAppear {
        AppDelegate.orientationLock = UIInterfaceOrientationMask.landscapeLeft
        UIDevice.current.setValue(UIInterfaceOrientation.landscapeLeft.rawValue, forKey: "orientation")
        UINavigationController.attemptRotationToDeviceOrientation()
    }
    .onDisappear {
        DispatchQueue.main.async {
            AppDelegate.orientationLock = UIInterfaceOrientationMask.portrait
            UIDevice.current.setValue(UIInterfaceOrientation.portrait.rawValue, forKey: "orientation")
            UINavigationController.attemptRotationToDeviceOrientation()
        }
    }
}
}

请注意 UIDevice 行中的 .rawValue 消除了“LongValue”错误。 此外,在 .onDisappear 中,我必须使用 DispatchQueue.main.async 以避免在返回到纵向视图时出现错误。

如果您的应用程序使用 SwiftUI 生命周期,则应用程序将使用符合应用程序协议的自定义结构启动。 您的应用程序没有实现上述解决方案所需的 AppDelegate。

要制作您自己的 AppDelegate,请在您的 appnameApp.swift 中尝试此代码

@main
struct appnameApp: App {
@UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
    var body: some Scene {
        WindowGroup {
            ContentView()
        }
    }
}

class AppDelegate: NSObject, UIApplicationDelegate {
    
    static var orientationLock = UIInterfaceOrientationMask.portrait
    
    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
        // something to do
        return true
    }
    
    func application(_ application: UIApplication, supportedInterfaceOrientationsFor window:UIWindow?) -> UIInterfaceOrientationMask {
        return AppDelegate.orientationLock
    }
}

来源: https : //www.hackingwithswift.com/quick-start/swiftui/how-to-add-an-appdelegate-to-a-swiftui-app

此外,您还可以进一步使用 go 并使用 Jonathan 的代码为视图 class 创建扩展,然后只需在要旋转的类上调用此扩展即可。

extension View {
    func unlockRotation() -> some View {
        onAppear {
            AppDelegate.orientationLock = UIInterfaceOrientationMask.allButUpsideDown
            UIViewController.attemptRotationToDeviceOrientation()
        }
        .onDisappear {
            AppDelegate.orientationLock = UIInterfaceOrientationMask.portrait
            UIDevice.current.setValue(UIInterfaceOrientation.portrait.rawValue, forKey: "orientation")
            UIViewController.attemptRotationToDeviceOrientation()
        }
    }
}

使用来自https://stackoverflow.com/a/41811798/10330141 的AppUtility

在 SwiftUI 中

创建自定义 UIHostingController

 class OrientationHostingController : UIHostingController<AnyView> {
    
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        
        AppUtility.lockOrientation(.portrait)
        
    }
 }




let rootView = OrientationHostingController(rootView: AnyView(SwiftUIView()))

对 Jonathan 的出色解决方案稍作改动。 这个版本回答了上面的人询问除了“landscapeLeft”之外如何使用其他方向。

首先,Jonathan 表示“我们将项目方向设置为仅支持纵向模式。” 如果您想允许其他方向,请不要这样做。 因此,对于该项目,如果您也希望此方向,请选中“Portrait”、“Landscape Left”和“Landscape Right”以及“Upside Down”。

其次,在您希望允许旋转的视图的onAppear中,设置以下内容:

AppDelegate.orientationLock = UIInterfaceOrientationMask.allButUpsideDown

以上内容替换了原始示例中的.landscapeLeft 注意,如果你想允许上下颠倒,把它改为.all

就是这样。 其他一切都如 Jonathan 和其他人所述。 结果是应用程序将纵向锁定,除了您使用onAppear和上面的代码更新的视图。 对于那些用户将可以访问所有方向(或所有但颠倒的方向)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM