Swift – 动态改变状态栏statusBar文字颜色(preferredStatusBarStyle无效问题)

    默认情况下,顶部状态栏(
statusBar)为
default 样式(文字为黑色),我们可以将其改为
light 样式(文字为白色),具体方法可以看我之前写的文章(
点击查看)     但之前我们都是在应用发布前就决定好样式。如果我们想要在程序运行中,能动态地改变状态栏样式也是可以做到的。这个根据是否有导航栏,分别有不同实现方式。

1,没有导航栏的情况

(1)如果没有使用导航控制器
UINavigationController, 或者说它的
navigationBar 被隐藏的话,那么我们需要重写
preferredStatusBarStyle 方法(在里面返回希望使用的样式),然后在需要更新的时候调用
setNeedsStatusBarAppearanceUpdate() 方法来触发它。 (2)下面是一个简单的样例,每次点击按钮,导航栏文字颜色会在白色和黑色之前切换。          
      

import UIKit

class ViewController: UIViewController {
    
    // 当前statusBar使用的样式
    var style: UIStatusBarStyle = .default

    // 重现statusBar相关方法
    override var preferredStatusBarStyle: UIStatusBarStyle {
        return self.style
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
    }
    
    // 每次点击按钮切换一次样式
    @IBAction func changeStyle(_ sender: Any) {
        if self.style == .lightContent {
            self.style = .default
        } else {
            self.style = .lightContent
        }
        setNeedsStatusBarAppearanceUpdate()
    }
}

2,有导航栏的情况

如果我们使用了导航控制器
UINavigationController, 且它的
navigationBar 没有被隐藏,那么会发现即使重写
preferredStatusBarStyle 方法,这个方法也不会被调用。因为此时状态栏的样式是根据导航栏的样式来自动变换的。 (1)下面样例当显示默认导航栏时,状态栏文字为黑色。当导航栏隐藏时,将状态栏文字设为白色。         
       

import UIKit

class ViewController: UIViewController {
    
    // 当前statusBar使用的样式
    var style: UIStatusBarStyle = .default
    
    // 重现statusBar相关方法
    override var preferredStatusBarStyle: UIStatusBarStyle {
        return self.style
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
    }
    
    // 每次点击按钮切换一次样式
    @IBAction func changeStyle(_ sender: Any) {
        if let isHidden = self.navigationController?.isNavigationBarHidden {
            // 切换导航栏显示或者隐藏
            self.navigationController?.isNavigationBarHidden = !isHidden
            // 更新状态栏颜色
            self.style = !isHidden ? .lightContent : .default
            setNeedsStatusBarAppearanceUpdate()
        }
    }
}

(2)下面样例在切换导航栏样式时,状态栏文字样式也会自动随之变换。当然我们也不需要重写
preferredStatusBarStyle 方法        
       

import UIKit

class ViewController: UIViewController {
    
    override func viewDidLoad() {
        super.viewDidLoad()
    }
    
    // 每次点击按钮切换一次样式
    @IBAction func changeStyle(_ sender: Any) {
        if let navigationBar = self.navigationController?.navigationBar {
            // 切换导航栏样式
            if navigationBar.barStyle == .default {
                navigationBar.barStyle = .black
            } else {
                navigationBar.barStyle = .default
            }
        }
    }
}

(3)即使我们修改了导航栏的背景色或者背景片,只要导航栏样式变化了,状态栏也会随之变化。      
        

import UIKit

class ViewController: UIViewController {
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        // 将导航栏背景色设置橙色
        self.navigationController?.navigationBar.barTintColor = UIColor.orange
    }
    
    // 每次点击按钮切换一次样式
    @IBAction func changeStyle(_ sender: Any) {
        if let navigationBar = self.navigationController?.navigationBar {
            // 切换导航栏样式
            if navigationBar.barStyle == .default {
                navigationBar.barStyle = .black
            } else {
                navigationBar.barStyle = .default
            }
        }
    }
}
THE END