swift - PreferredStatusBarHidden 在调用 setNeedsStatusBarAppearanceUpdate() 后不更新

标签 swift uiviewcontroller uinavigationcontroller uiwindow uistatusbar

我的应用程序内的不同 vcs 显示状态栏可见,而其他 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 个窗口,主窗口和第二个窗口。通过按下按钮,第二个窗口将显示在主窗口的前面。第二个窗口中的 vc 隐藏了状态栏。

问题是,如果我在显示状态栏的主窗口内的 vc (mainVC) 上,我按下按钮显示第二个窗口,mainVC 的状态栏就会消失。第二个窗口出现,在我关闭它后,我向 mainVC 发送通知以调用 setNeedsStatusBarAppearanceUpdate()prefersStatusBarHidden 未触发,因此状态栏保持隐藏状态,即使它不应该。我什至对导航 Controller 进行了子类化,并以 mainVC 作为根添加了代码。

为什么prefersStatusBarHidden没有被调用?

我在 mainVC 内部添加了 prefersStatusBarHidden ,将导航添加到 mainVC 中,然后同时在 mainVC 和它的导航中添加。在任一位置调用 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

最佳答案

更新状态栏需要在主线程上。

有两种方法可以确保:

在主线程添加通知观察器:(不需要将 func 暴露给 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()
    }
}

关于swift - PreferredStatusBarHidden 在调用 setNeedsStatusBarAppearanceUpdate() 后不更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51112254/

相关文章:

ios - 如何更改压入堆栈的 View Controller 的标题颜色?

ios - 为什么 cell.ImageView?.image 如果传递了图像则为 nil?与 Swift 中的可选项混淆

ios - 从 Swift 中的不同类访问 ViewController 中的对象

ios - 在 prepareForSegue 方法中防止 segue?

IOS 切换 View 和 Storyboard不起作用

ios - 如何正确使用popToViewController?

ios - Swift Storyboard - 水平居中图标和多行文本

javascript - 从swift调用 Angular 函数

Swift:使用 StoryBoard 在 Tableview 上 float 加号按钮

ios - 选项卡和导航 View Controller 中表格单元格的 Segue