调用 setNeedsStatusBarAppearanceUpdate() 后 prefersStatusBarHidden 未更新
prefersStatusBarHidden not updating after calling setNeedsStatusBarAppearanceUpdate()
我的应用程序中的不同 vcs 显示状态栏可见,而其他的则隐藏。这在 info.pList
中设置为 YES
"View controller-based status bar appearance": YES
// also tried togging this between yes and no
"Status bar is initially hidden": YES
该应用程序有 2 个 windows,主要 window 和第二个 window。第二个 window 会在按下按钮时出现在主 window 的前面。第二个window中的vc隐藏了状态栏。
问题是如果我在显示状态栏的主要 window 内的 vc (mainVC) 上,我按下按钮显示第二个 window, mainVC 的状态栏消失了。第二个 window 出现,在我关闭它后,我向 mainVC 发送通知以调用 setNeedsStatusBarAppearanceUpdate()
但 prefersStatusBarHidden
未被触发,因此状态栏保持隐藏状态,即使它不应该被隐藏.我什至对导航控制器进行了子类化,并在其中添加了带有 mainVC 的代码,因为它是根。
为什么 prefersStatusBarHidden
没有接到电话?
我在 mainVC 中单独添加了 prefersStatusBarHidden
,将 nav 单独添加到 mainVC 中,然后同时在 mainVC 和它的 nav 中添加。 setNeedsStatusBarAppearanceUpdate()
在任何一个地方被调用后仍然没有被调用。
子类导航:
class MainVCNavController: UINavigationController {
override init(rootViewController: UIViewController) {
super.init(rootViewController: rootViewController)
NotificationCenter.default.addObserver(self, selector: #selector(updateStatusBar), name: NSNotification.Name(rawValue: "updateStatusBar"), object: nil)
}
let statusBarHidden: Bool = false
@objc func updateStatusBar() {
self.setNeedsStatusBarAppearanceUpdate() // this gets called when the notification is triggered
}
override var prefersStatusBarHidden: Bool {
return statusBarHidden // this doesn't get called after setNeedsStatusBarAppearanceUpdate() is called
}
// I added this just to see if it would make a difference but it didn't
override var preferredStatusBarUpdateAnimation: UIStatusBarAnimation {
return .slide
}
override open var childViewControllerForStatusBarStyle: UIViewController? {
return self.topViewController
}
override open var childViewControllerForStatusBarHidden: UIViewController? {
return self.topViewController
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {
super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
}
}
MainVC是上面nav的rootVC
class MainVCController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
NotificationCenter.default.addObserver(self, selector: #selector(updateStatusBar), name: NSNotification.Name(rawValue: "updateStatusBar"), object: nil)
}
let statusBarHidden: Bool = false
@objc func updateStatusBar() {
self.setNeedsStatusBarAppearanceUpdate() // this gets called when the notification is called
}
override var prefersStatusBarHidden: Bool {
return statusBarHidden // this doesn't get called after setNeedsStatusBarAppearanceUpdate() is triggered
}
// I added this just to see if it would make a difference but it didn't
override var preferredStatusBarUpdateAnimation: UIStatusBarAnimation {
return .slide
}
}
第二个 window 中的 SecondVC 隐藏了状态栏。当它被解除时发送通知到上面的 mainVC:
class SecondController: UIViewController {
override var prefersStatusBarHidden: Bool {
return true
}
if dismissed {
NotificationCenter.default.post(name: Notification.Name(rawValue: "updateStatusBar"), object: nil)
}
}
我还读到我需要调用下面的方法来触发 prefersStatusBarHidden
但即使我将这些添加到 updateStatusBar()
也没有什么不同。
navigationController?.setNavigationBarHidden(false, animated: false)
// or
navigationController?.navigationBar.isHidden = false
@zombie 关于主线程更新的回答 100% 有效。另一方面,他还建议我使用符号断点来诊断问题。他提供了很好的 link 帮助:
更新状态栏需要在主线程。
有两种方法可以确保:
在主线程上添加通知观察者:(你不需要将函数暴露给objc c):
NotificationCenter.default.addObserver(forName: NSNotification.Name(rawValue: "updateStatusBar"), object: nil, queue: .main, using: updateStatusBar)
func updateStatusBar(_ notification: Notification) {
setNeedsStatusBarAppearanceUpdate()
}
或者在主线程更新状态栏:
NotificationCenter.default.addObserver(self, selector: #selector(updateStatusBar(_:)), name: NSNotification.Name(rawValue: "updateStatusBar"), object: nil)
@objc func updateStatusBar(_ notification: Notification) {
DispatchQueue.main.sync {
self.setNeedsStatusBarAppearanceUpdate()
}
}
我的应用程序中的不同 vcs 显示状态栏可见,而其他的则隐藏。这在 info.pList
中设置为 YES "View controller-based status bar appearance": YES
// also tried togging this between yes and no
"Status bar is initially hidden": YES
该应用程序有 2 个 windows,主要 window 和第二个 window。第二个 window 会在按下按钮时出现在主 window 的前面。第二个window中的vc隐藏了状态栏。
问题是如果我在显示状态栏的主要 window 内的 vc (mainVC) 上,我按下按钮显示第二个 window, mainVC 的状态栏消失了。第二个 window 出现,在我关闭它后,我向 mainVC 发送通知以调用 setNeedsStatusBarAppearanceUpdate()
但 prefersStatusBarHidden
未被触发,因此状态栏保持隐藏状态,即使它不应该被隐藏.我什至对导航控制器进行了子类化,并在其中添加了带有 mainVC 的代码,因为它是根。
为什么 prefersStatusBarHidden
没有接到电话?
我在 mainVC 中单独添加了 prefersStatusBarHidden
,将 nav 单独添加到 mainVC 中,然后同时在 mainVC 和它的 nav 中添加。 setNeedsStatusBarAppearanceUpdate()
在任何一个地方被调用后仍然没有被调用。
子类导航:
class MainVCNavController: UINavigationController {
override init(rootViewController: UIViewController) {
super.init(rootViewController: rootViewController)
NotificationCenter.default.addObserver(self, selector: #selector(updateStatusBar), name: NSNotification.Name(rawValue: "updateStatusBar"), object: nil)
}
let statusBarHidden: Bool = false
@objc func updateStatusBar() {
self.setNeedsStatusBarAppearanceUpdate() // this gets called when the notification is triggered
}
override var prefersStatusBarHidden: Bool {
return statusBarHidden // this doesn't get called after setNeedsStatusBarAppearanceUpdate() is called
}
// I added this just to see if it would make a difference but it didn't
override var preferredStatusBarUpdateAnimation: UIStatusBarAnimation {
return .slide
}
override open var childViewControllerForStatusBarStyle: UIViewController? {
return self.topViewController
}
override open var childViewControllerForStatusBarHidden: UIViewController? {
return self.topViewController
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {
super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
}
}
MainVC是上面nav的rootVC
class MainVCController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
NotificationCenter.default.addObserver(self, selector: #selector(updateStatusBar), name: NSNotification.Name(rawValue: "updateStatusBar"), object: nil)
}
let statusBarHidden: Bool = false
@objc func updateStatusBar() {
self.setNeedsStatusBarAppearanceUpdate() // this gets called when the notification is called
}
override var prefersStatusBarHidden: Bool {
return statusBarHidden // this doesn't get called after setNeedsStatusBarAppearanceUpdate() is triggered
}
// I added this just to see if it would make a difference but it didn't
override var preferredStatusBarUpdateAnimation: UIStatusBarAnimation {
return .slide
}
}
第二个 window 中的 SecondVC 隐藏了状态栏。当它被解除时发送通知到上面的 mainVC:
class SecondController: UIViewController {
override var prefersStatusBarHidden: Bool {
return true
}
if dismissed {
NotificationCenter.default.post(name: Notification.Name(rawValue: "updateStatusBar"), object: nil)
}
}
我还读到我需要调用下面的方法来触发 prefersStatusBarHidden
但即使我将这些添加到 updateStatusBar()
也没有什么不同。
navigationController?.setNavigationBarHidden(false, animated: false)
// or
navigationController?.navigationBar.isHidden = false
@zombie 关于主线程更新的回答 100% 有效。另一方面,他还建议我使用符号断点来诊断问题。他提供了很好的 link 帮助:
更新状态栏需要在主线程。
有两种方法可以确保:
在主线程上添加通知观察者:(你不需要将函数暴露给objc c):
NotificationCenter.default.addObserver(forName: NSNotification.Name(rawValue: "updateStatusBar"), object: nil, queue: .main, using: updateStatusBar)
func updateStatusBar(_ notification: Notification) {
setNeedsStatusBarAppearanceUpdate()
}
或者在主线程更新状态栏:
NotificationCenter.default.addObserver(self, selector: #selector(updateStatusBar(_:)), name: NSNotification.Name(rawValue: "updateStatusBar"), object: nil)
@objc func updateStatusBar(_ notification: Notification) {
DispatchQueue.main.sync {
self.setNeedsStatusBarAppearanceUpdate()
}
}