bounty 5天后到期。这个问题的答案有资格获得+50的声誉奖励。Deepak Sharma正在寻找规范答案。
我在iOS 16上看到了一个奇怪的问题,这在其他iOS版本中是没有的。更糟糕的是,如果我将设备连接到XCode并进行调试,则看不到该问题。只有当我通过触摸应用程序图标直接在设备上启动应用程序时才能看到它,这就是我无法识别任何修复程序的原因。我所做的是在应用程序启动时禁用自动旋转(通过在supportedInterfaceOrientations
中仅返回.scape),然后在0.2秒后不久,我强制自动旋转到设备的当前界面方向(使用self.setNeedsUpdateOfSupportedInterfaceOrientations
)。但如果直接通过触摸应用程序图标启动应用程序(而不是从调试器启动),自动旋转就会失败!
以下是完整再现该问题的示例代码。在运行该应用程序时,请确保iPhone处于纵向模式。不会调用函数viewWillTransition(to size:, with coordinator:)
,也不会自动旋转所有子视图。请给我推荐一种解决办法!
import UIKit
class ViewController: UIViewController {
public var windowOrientation: UIInterfaceOrientation {
return view.window?.windowScene?.interfaceOrientation ?? .unknown
}
private var disableAutoRotation = true
override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
var orientations:UIInterfaceOrientationMask = .landscapeRight
if !self.disableAutoRotation {
orientations = .all
}
return orientations
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
self.view.backgroundColor = UIColor.systemGreen
DispatchQueue.main.asyncAfter(deadline: .now() + 0.2, execute: {
self.autoRotateNotification()
})
}
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
super.viewWillTransition(to: size, with: coordinator)
let orientation = windowOrientation
coordinator.animate(alongsideTransition: {_ in
}, completion: { [unowned self] (UIViewControllerTransitionCoordinatorContext) -> Void in
let orient = self.windowOrientation
if orient.isLandscape {
self.view.backgroundColor = UIColor.systemGreen
} else {
self.view.backgroundColor = UIColor.systemOrange
}
})
}
func autoRotateNotification() {
DispatchQueue.main.asyncAfter(deadline: .now(), execute: {
/*
* HELP::: This code does something only when debug directly from XCode,
* not when directly launching the app on device!!!!
*/
self.disableAutoRotation = false
if #available(iOS 16.0, *) {
UIView.performWithoutAnimation {
self.setNeedsUpdateOfSupportedInterfaceOrientations()
}
} else {
// Fallback on earlier versions
UIViewController.attemptRotationToDeviceOrientation()
}
})
}
}
编辑:有人提到将autorotateNotify移到viewDidAppear
可以解决这个问题,但它不能。如前所述,如果APP是通过XCode调试器启动的,这是没有问题的。仅当通过触摸应用程序图标直接启动应用程序时,才会观察到该问题!下面是每个同样失败的引用的示例代码。
import UIKit
class ViewController: UIViewController {
public var windowOrientation: UIInterfaceOrientation {
return view.window?.windowScene?.interfaceOrientation ?? .unknown
}
private var disableAutoRotation = true
override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
var orientations:UIInterfaceOrientationMask = .landscapeRight
if !self.disableAutoRotation {
orientations = .all
}
return orientations
}
override var preferredInterfaceOrientationForPresentation: UIInterfaceOrientation {
return .landscapeLeft
}
private var autoRotated = false
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
if !autoRotated {
autoRotated = true
self.autoRotateNotification()
}
}
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
super.viewWillTransition(to: size, with: coordinator)
coordinator.animate(alongsideTransition: {_ in
}, completion: { [unowned self] (UIViewControllerTransitionCoordinatorContext) -> Void in
let orient = self.windowOrientation
if orient.isLandscape {
self.view.backgroundColor = UIColor.systemGreen
} else {
self.view.backgroundColor = UIColor.systemOrange
}
})
}
func autoRotateNotification() {
self.disableAutoRotation = false
if #available(iOS 16.0, *) {
self.setNeedsUpdateOfSupportedInterfaceOrientations()
} else {
// Fallback on earlier versions
UIViewController.attemptRotationToDeviceOrientation()
}
}
}
1条答案
按热度按时间hlswsv351#
viewWillTransition
似乎未被调用,因为您的函数autoRotateNotification()
是从viewDidLoad
函数调用的,而该视图在屏幕上仍然不可见。尝试将您的代码移动到
viewDidAppear
中,将调用viewWillTransition。这是我的工作代码: