I have one view, that need to be locked in portrait only on the iPhone, but not on the iPad, but while it seems to be kinda easy on UIKit, I cannot find any solution for the SwiftUI. For UIKit it works through overriding supportedInterfaceOrientations in the controller, but I don't see any easy way to do so in the SwiftUI
How to lock screen orientation for a specific view?
Oooh, I know this one! There's a discussion here: SwiftUI: Force orientation on a per screen basis.
I also implemented this as part of my open-source toolkit: https://github.com/AlanQuatermain/AQUI/blob/master/Sources/AQUI/OrientationLock.swift
The version on Github allows views to specify their individual constraints, and will collapse them all into a single allowable state. If one view says 'all but upside down' and another says 'portrait only' then the effective value will be 'portrait only'.
struct NetflixApp: App {
@UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
}
class AppDelegate: NSObject {
// 屏幕旋转锁定
static var orientationLock = UIInterfaceOrientationMask.portrait
}
extension AppDelegate: UIApplicationDelegate {
func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {
return AppDelegate.orientationLock
}
}
SomeView
.onDisappear(perform: {
DispatchQueue.main.async {
AppDelegate.orientationLock = UIInterfaceOrientationMask.portrait
UIDevice.current.setValue(UIInterfaceOrientation.portrait.rawValue, forKey: "orientation")
UINavigationController.attemptRotationToDeviceOrientation()
}
})
.onAppear(perform: {
AppDelegate.orientationLock = UIInterfaceOrientationMask.landscape
UIDevice.current.setValue(UIInterfaceOrientation.landscapeLeft.rawValue, forKey: "orientation")
UINavigationController.attemptRotationToDeviceOrientation()
})
@UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
}
class AppDelegate: NSObject {
// 屏幕旋转锁定
static var orientationLock = UIInterfaceOrientationMask.portrait
}
extension AppDelegate: UIApplicationDelegate {
func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {
return AppDelegate.orientationLock
}
}
SomeView
.onDisappear(perform: {
DispatchQueue.main.async {
AppDelegate.orientationLock = UIInterfaceOrientationMask.portrait
UIDevice.current.setValue(UIInterfaceOrientation.portrait.rawValue, forKey: "orientation")
UINavigationController.attemptRotationToDeviceOrientation()
}
})
.onAppear(perform: {
AppDelegate.orientationLock = UIInterfaceOrientationMask.landscape
UIDevice.current.setValue(UIInterfaceOrientation.landscapeLeft.rawValue, forKey: "orientation")
UINavigationController.attemptRotationToDeviceOrientation()
})