[英]is Force View Controller Orientation working in iOS 16 beta
根据 iOS 和 iPadOS 16 Beta 3 发行说明:- 尝试通过setValue:forKey:
在UIDevice上设置方向不受支持且不再有效。 相反,他们说使用:preferredInterfaceOrientationForPresentation。
就我而言,通过使用preferredInterfaceOrientationForPresentation
或requestGeometryUpdate
强制视图控制器方向在 iOS 16 beta 中不起作用。
以前, UIDevice.current.setValue(UIInterfaceOrientation.landscapeLeft.rawValue, forKey: "orientation")
工作正常。
这个对我有用:
import Foundation
import UIKit
extension UIViewController {
func setDeviceOrientation(orientation: UIInterfaceOrientationMask) {
if #available(iOS 16.0, *) {
let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene
windowScene?.requestGeometryUpdate(.iOS(interfaceOrientations: orientation))
} else {
UIDevice.current.setValue(orientation.toUIInterfaceOrientation.rawValue, forKey: "orientation")
}
}
}
extension UIInterfaceOrientationMask {
var toUIInterfaceOrientation: UIInterfaceOrientation {
switch self {
case .portrait:
return UIInterfaceOrientation.portrait
case .portraitUpsideDown:
return UIInterfaceOrientation.portraitUpsideDown
case .landscapeRight:
return UIInterfaceOrientation.landscapeRight
case .landscapeLeft:
return UIInterfaceOrientation.landscapeLeft
default:
return UIInterfaceOrientation.unknown
}
}
}
如何使用它?
只需在您的 UIViewController 上调用它:
setDeviceOrientation(orientation: .landscapeRight)
编辑
更完整的解决方案:
import UIKit
final class DeviceOrientation {
static let shared: DeviceOrientation = DeviceOrientation()
// MARK: - Private methods
private var windowScene: UIWindowScene? {
return UIApplication.shared.connectedScenes.first as? UIWindowScene
}
// MARK: - Public methods
func set(orientation: UIInterfaceOrientationMask) {
if #available(iOS 16.0, *) {
windowScene?.requestGeometryUpdate(.iOS(interfaceOrientations: orientation))
} else {
UIDevice.current.setValue(orientation.toUIInterfaceOrientation.rawValue, forKey: "orientation")
}
}
var isLandscape: Bool {
if #available(iOS 16.0, *) {
return windowScene?.interfaceOrientation.isLandscape ?? false
}
return UIDevice.current.orientation.isLandscape
}
var isPortrait: Bool {
if #available(iOS 16.0, *) {
return windowScene?.interfaceOrientation.isPortrait ?? false
}
return UIDevice.current.orientation.isPortrait
}
var isFlat: Bool {
if #available(iOS 16.0, *) {
return false
}
return UIDevice.current.orientation.isFlat
}
}
extension UIInterfaceOrientationMask {
var toUIInterfaceOrientation: UIInterfaceOrientation {
switch self {
case .portrait:
return UIInterfaceOrientation.portrait
case .portraitUpsideDown:
return UIInterfaceOrientation.portraitUpsideDown
case .landscapeRight:
return UIInterfaceOrientation.landscapeRight
case .landscapeLeft:
return UIInterfaceOrientation.landscapeLeft
default:
return UIInterfaceOrientation.unknown
}
}
}
如何使用它:
DeviceOrientation.shared.set(orientation: .portrait)
我注意到我的问题似乎可以通过调用以下方法解决:
[UIViewController setNeedsUpdateOfSupportedInterface
你可以试一试。
setValue:forKey
是旧NSObject
( NSKeyValueCoding
) 的方法。 UIDevice
class 没有官方记录和支持。 使用它正在考虑使用私有 api。 苹果可以随时终止它。
我在下面的代码中遇到的问题是,我在关闭模态视图时尝试这样做,而它下面的视图更新得不够快。 如果我将 requestGeometryUpdate 放在一个单独的按钮上,那么当我关闭视图时它就会起作用。
if #available(iOS 16.0, *) {
let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene
windowScene?.requestGeometryUpdate(.iOS(interfaceOrientations: .portrait))
}
Apple 发布了新的 API 替换为 setValue:forKey:"orientation"。 苹果更新
guard let windowScene = view.window?.windowScene else { return }
windowScene.requestGeometryUpdate(.iOS(interfaceOrientations: .landscape)) { error in
// Handle denial of request.
}
但我对UIDevice.orientationDidChangeNotification
有问题,它不工作
这个对我有用。
在 AppDelegate 中,
var orientation: UIInterfaceOrientationMask = .portrait
func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {
return orientation
}
鉴于controller,
(UIApplication.shared.delegate as? AppDelegate)?.orientation = .landscapeRight
let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene
windowScene?.requestGeometryUpdate(.iOS(interfaceOrientations: .landscapeRight))
UIApplication.navigationTopViewController()?.setNeedsUpdateOfSupportedInterfaceOrientations()
按照 Apple 的文档,您需要
使用指定的几何首选项对象请求更新窗口场景的几何图形。
https://developer.apple.com/documentation/uikit/uiwindowscene/3975944-requestgeometryupdate/
因此,使用示例中的代码,您可以使用requestGeometryUpdate
和setNeedsUpdateOFSupportedInterface
更改我们在视图中设置方向的方式
public extension UIViewController {
func deviceOrientation(orientation: UIInterfaceOrientationMask) {
if #available(iOS 16.0, *) {
guard let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene
else { return }
windowScene.requestGeometryUpdate(.iOS(interfaceOrientations: orientation))
self.setNeedsUpdateOfSupportedInterfaceOrientations()
}
}
}
我尝试了以上所有解决方案,但它们似乎并非 100% 有效。 通过这篇文章https://developer.apple.com/forums/thread/707735我得到了提示。 让我们试试下面的代码。 它对我有用。
if #available(iOS 16.0, *) {
DispatchQueue.main.async {
UIViewController.attemptRotationToDeviceOrientation()
let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene
windowScene?.requestGeometryUpdate(.iOS(interfaceOrientations: orientation)) { error in
print(error)
print(windowScene?.effectiveGeometry)
}
navigationController?.topViewController?.setNeedsUpdateOfSupportedInterfaceOrientations()
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.