我的应用程序内的不同vc显示状态栏可见,而其他vc隐藏。在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个窗口,主窗口和第二个窗口。按下按钮,第二个窗口将显示在主窗口的前面。第二个窗口中的vc隐藏了状态栏。
问题是,如果我位于显示状态栏的主窗口内的vc(mainVC)上,则按下按钮以显示第二个窗口,mainVC的状态栏消失了。第二个窗口显示出来,我将其关闭后,我向mainVC发送通知以调用setNeedsStatusBarAppearanceUpdate()
,但是prefersStatusBarHidden
未被触发,因此状态栏保持隐藏,即使不应该隐藏。我什至为导航控制器创建了子类,并在其中添加了以mainVC为根的代码。
为什么没有prefersStatusBarHidden
被打?
我将prefersStatusBarHidden
单独添加到mainVC内,将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是上述导航的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
}
}
第二个窗口内的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
答案 0 :(得分:1)
更新状态栏需要在主线程上。
有两种方法可以确保:
在主线程上添加通知观察器:(您无需将函数公开给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()
}
}
答案 1 :(得分:0)
@zombie关于100%有效的主线程更新的答案。另一方面,他还建议我使用符号断点来诊断问题。他提供了一个很棒的帮助链接: