如何在Swift 3中设置状态栏样式

203

我正在使用Xcode 8.0 beta 4。

在之前的版本中,UIViewController有方法可以设置状态栏样式。

public func preferredStatusBarStyle() -> UIStatusBarStyle

然而,我发现在Swift 3中它变成了一个 "仅获取变量"。

public var preferredStatusBarStyle: UIStatusBarStyle { get } 

我该如何为我的UIViewController提供样式?


请尝试以下代码:var preferredStatusBarStyle: UIStatusBarStyle = .lightContent - Anbu.Karthik
33个回答

14

Swift 5

为了对 PRAVEENhttps://dev59.com/7lkT5IYBdhLWcg3wV-GZ#40066798 的回答添加更多细节,我想提供我的实现方式。它支持 灵活性,可以自定义每个控制器的状态栏。

总体上,我们将创建一个名为BaseViewController的类来处理所有情况下的statusBarStyle属性。每当您创建一个新控制器时,将其设置为此基础控制器的子类。

每当您想要改变状态栏外观时,只需要更新此属性即可。状态栏样式会立即更新。

实现

class BaseViewController: UIViewController {

    var statusBarStyle: UIStatusBarStyle = .default {
        didSet {
            setNeedsStatusBarAppearanceUpdate()
        }
    }

    override var preferredStatusBarStyle: UIStatusBarStyle {
        return statusBarStyle
    }
}

演示

class ViewController: BaseViewController, UIScrollViewDelegate {

    let scrollView = UIScrollView()
    ... 
    func scrollViewDidScroll(_ scrollView: UIScrollView) {
        UIView.animate(withDuration: 0.3) {
            if scrollView.contentOffset.y > 30 {
                self.statusBarStyle = .darkContent
            } else {
                self.statusBarStyle = .lightContent
            }
        }
    }
}

图片描述

2. UINavigationController

对于UINavigationController,它是一个特殊情况,您可以按以下任一解决方案操作:

解决方案A:使用消息分发覆盖

由于UINavigationController是一个NSObject并且继承自ObjectiveC,其方法是消息分发,因此您可以覆盖它们。

extension UINavigationController {
   open override var preferredStatusBarStyle: UIStatusBarStyle {
      return topViewController?.preferredStatusBarStyle ?? .default
   }
}

解决方案B:创建UINavigationController子类

如果您已经有了自定义的UINavigationController(通常需要控制更多的需求),那么这是最好的解决方案。

final class NavigationController: UINavigationController {
    override var preferredStatusBarStyle: UIStatusBarStyle {
        return topViewController?.preferredStatusBarStyle ?? super.preferredStatusBarStyle
    }
}

10
  1. 选择 轻量级内容enter image description here

  2. .plist 中添加 基于视图控制器的状态栏外观 并设置为 NO enter image description here


这是正确的答案。 - Anton

10

首先,您需要添加一个键为View controller-based status bar appearance值为NO的行到Info.plist文件中。之后,在您的控制器中添加2个函数,以仅特定控制器受影响:

override func viewWillAppear(_ animated: Bool) {
       super.viewWillAppear(animated)
       UIApplication.shared.statusBarStyle = .lightContent
}

override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
        UIApplication.shared.statusBarStyle = .default    
}

谢谢,它起作用了。其他所有解决方案对我都不起作用。 - mattom

8

在处理导航栏时,状态栏文本颜色似乎存在一些小问题。

如果您想要将 .plist 条目“View controller-based status bar appearance”设置为 YES,当您使用有颜色的导航栏时,它有时不起作用。

例如:

override func viewWillAppear(_ animated: Bool) {
    let nav = self.navigationController?.navigationBar
    nav?.barTintColor = .red
    nav?.tintColor = .white
    nav?.titleTextAttributes = [NSAttributedStringKey.foregroundColor: UIColor.white]
    setNeedsStatusBarAppearanceUpdate()
}

并且

override var preferredStatusBarStyle: UIStatusBarStyle {return .lightContent}

即使您在AppDelegate中设置了以下内容,上述代码也无法工作:

UIApplication.shared.statusBarStyle = .lightContent

对于那些仍在苦苦挣扎的人来说,显然它通过导航栏中的样式来判断状态栏是否需要变为浅色或深色。因此,我通过在viewWillAppear中添加以下行来解决此问题:

nav?.barStyle = UIBarStyle.black

当导航栏样式为黑色时,它会依从您重写的变量。希望这能帮助到某些人 :)


7

Xcode 8.3.1,Swift 3.1

  1. 在info.plist中创建一个新的条目“View controller-based status bar appearance”,将其设置为“NO”。

  2. 打开AppDelegate.swift并在“didFinishLaunchingWithOptions”方法中添加以下行:

application.statusBarStyle = .lightContent


7

Swift 3

在 Info.plist 中添加一行名为“View controller-based status bar appearance”的内容,并将其值设置为 No

class YourViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        UIApplication.shared.statusBarStyle = .lightContent //or .default
        setNeedsStatusBarAppearanceUpdate()

    }

}

7

在@Krunal的出色回答中,我想补充一些内容。https://dev59.com/7lkT5IYBdhLWcg3wV-GZ#49552326

如果您正在使用UINavigationController,则preferredStatusBarStyleUIViewController没有影响。

Xcode 10和Swift 4。

设置自定义UINavigationController

示例:

class LightNavigationController: UINavigationController {

   open override var preferredStatusBarStyle: UIStatusBarStyle {
       return .lightContent
   }
}

使用扩展程序作为应用级解决方案:

extension UINavigationController {

  open override var preferredStatusBarStyle: UIStatusBarStyle {
      guard let index = tabBarController?.selectedIndex else { return .default }
      switch index {
      case 0, 1, 2: return .lightContent // set lightContent for tabs 0-2
      default: return .default // set dark for tab 3
      }
  }
}

6

Swift 4+

如果需要白色状态栏文字:

navigationController.navigationBar.barStyle = .blackTranslucent

6

这里是关于状态栏样式更改的苹果指南/说明书

如果您想设置应用程序级别的状态栏样式,请在您的.plist文件中将UIViewControllerBasedStatusBarAppearance设置为NO。并且在您的appdelegate>didFinishLaunchingWithOptions中添加以下行(您可以从应用程序委托以编程方式执行此操作)。

Objective C

[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent animated:YES];

Swift

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
    application.statusBarStyle = .lightContent
    return true
}

如果您想在视图控制器级别设置状态栏样式,请按照以下步骤操作:
  1. .plist 文件中将 UIViewControllerBasedStatusBarAppearance 设置为 YES,仅在 UIViewController 级别需要设置状态栏样式时才需执行此步骤。
  2. 在 viewDidLoad 中添加函数 - setNeedsStatusBarAppearanceUpdate

  3. 覆盖您的视图控制器中的 preferredStatusBarStyle。

Objective C

- (void)viewDidLoad
{
    [super viewDidLoad];
    [self setNeedsStatusBarAppearanceUpdate];
}

- (UIStatusBarStyle)preferredStatusBarStyle
{
    return UIStatusBarStyleLightContent;
}

Swift

override func viewDidLoad() {
    super.viewDidLoad()
    self.setNeedsStatusBarAppearanceUpdate()
}

override var preferredStatusBarStyle: UIStatusBarStyle {
    return .lightContent
}

根据状态栏样式设置级别,设置 .plist 的值。

enter image description here


5

Swift 4.0 请在"didFinishLaunchingWithOptions launchOptions:" Appdelegate类中使用以下代码

UIApplication.shared.statusBarStyle = .lightContent
let statusBar: UIView = UIApplication.shared.value(forKey: "statusBar") as! UIView
if statusBar.responds(to: #selector(setter: UIView.backgroundColor)){
  statusBar.backgroundColor = UIColor.black
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接