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 中作为 Jonathan 上面的回答:
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 以避免在返回到之前的纵向视图时出现错误。
使用来自
的 AppUtility
在 SwiftUI 中
创建自定义 UIHostingController
class OrientationHostingController : UIHostingController<AnyView> {
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
AppUtility.lockOrientation(.portrait)
}
}
let rootView = OrientationHostingController(rootView: AnyView(SwiftUIView()))
如果您的应用程序正在使用 SwiftUI lifeCycle,则该应用程序将使用符合 App 协议的自定义结构启动。您的应用没有实现上述解决方案所需的 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
另外,您可以更进一步,使用 Jonathan 的代码为视图 class 创建一个扩展,然后简单地在您想要旋转的 classes 上调用这个扩展。
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()
}
}
}
我有一个 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 中作为 Jonathan 上面的回答:
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 中
创建自定义 UIHostingController
class OrientationHostingController : UIHostingController<AnyView> {
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
AppUtility.lockOrientation(.portrait)
}
}
let rootView = OrientationHostingController(rootView: AnyView(SwiftUIView()))
如果您的应用程序正在使用 SwiftUI lifeCycle,则该应用程序将使用符合 App 协议的自定义结构启动。您的应用没有实现上述解决方案所需的 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
另外,您可以更进一步,使用 Jonathan 的代码为视图 class 创建一个扩展,然后简单地在您想要旋转的 classes 上调用这个扩展。
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()
}
}
}