【问题标题】:iOS 7 and later: set status bar style per view controlleriOS 7 及更高版本:为每个视图控制器设置状态栏样式
【发布时间】:2013-10-01 13:54:40
【问题描述】:


我尝试了许多方法来设置状态栏样式(默认或 lightcontent),但无法让它在每个视图控制器的基础上工作。我只能为整个应用设置状态栏样式。

有人有提示吗?

我试过UIViewControllerBasedStatusBarAppearance

-(UIStatusBarStyle)preferredStatusBarStyle{ 
    return UIStatusBarStyleLightContent; 
}

但这些方法不起作用。

【问题讨论】:

  • 并确保导航栏不与状态栏重叠......
  • 我使用了一个小技巧(以及控制可见/隐藏状态)——我决定将其发布为 pod 'UIViewController+ODStatusBar' (cocoapods.org/pods/UIViewController+ODStatusBar)
  • 这只是 Apple 随机将 iOS 版本的行为更改为下一个版本的几十个 API 之一,并且由于某种原因,开发人员还没有完全反抗。您必须修改您的实现以适应您的应用运行的 iOS 版本,并在每次构建新版本时对其进行测试。

标签: ios cocoa-touch


【解决方案1】:

你试过了吗?

  1. 在 Info.plist 中将“基于控制器的状态栏外观”(UIViewControllerBasedStatusBarAppearance) 设置为 YES。 (YES 是默认值,因此您也可以将此值保留在 plist 之外。)

  2. 在你的 viewDidLoad 方法中,调用[self setNeedsStatusBarAppearanceUpdate]

  3. 实现preferredStatusBarStyle,返回此视图控制器所需的状态栏样式。

    - (UIStatusBarStyle) preferredStatusBarStyle { 
        return UIStatusBarStyleLightContent; 
    }
    

【讨论】:

  • 我不需要第 1 步
  • 这项功能适用于 Iphone 5 + ios7。 UIViewControllerBasedStatusBarAppearance 为 NO 并且 [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleBlackTranslucent];我的情况很好:)
  • @vishal 与基于 UINavigationController 的应用程序一起使用,如果您将该代码放入自定义 UINavigationController 子类中
  • 您不需要第二步。
  • 在 iOS 8 中对我不起作用。这只是更改了默认值。我需要的是白色的,现在使用默认设置。
【解决方案2】:

如果您的视图控制器位于独立的 UINavigationController 内部而不是基于 Storyboard 的 UINavigationController 的一部分,那么这里有一个问题,那么所有方法都会失败。我遇到了这种情况,然后为了将状态栏设置为浅色,我使用了以下

[self.navigationController.navigationBar setBarStyle:UIBarStyleBlack];

这对我来说非常有效。

【讨论】:

  • 如果您的导航控制器的导航栏被隐藏,则不起作用。
  • 类似的建议适用于 UISplitViewController。我最终进行了子类化。
  • 据我了解,UINavigationBar.barStyle 会覆盖preferredStatusBarStyle。不管你如何设置preferredStatusBarStyle,一个该死的 `UINavigationBar.setBarStyle' 会接管一切。
【解决方案3】:

编辑:此解决方案在 iOS 9 上已弃用。请选择其他答案之一。

UIViewControllerBasedStatusBarAppearance 设置为 NO,我可以使用以下方法将样式设置为白色文本:

[UIApplication sharedApplication].statusBarStyle = UIStatusBarStyleBlackTranslucent;

这是因为这种样式的文字颜色在 iOS 6 及更低版本上是白色的。

更新:根据@jowie,您可以在 iOS8 上尝试:

[UIApplication sharedApplication].statusBarStyle = UIBarStyleBlack;

【讨论】:

  • 你仔细阅读问题了吗?他要求 iOS7 解决方案以及它的浅色风格,而不是你的情况。
  • 它适用于iOS7。我确实仔细阅读了它。关于 UIBarStyleBlackTranslucent,它之所以有效,是因为 iOS6 上的这种样式是黑色背景(半透明)和白色文本。当您在 iOS7 上执行此操作时,它只会以白色显示文本。我知道它看起来很老套,但这是我发现真正控制酒吧的唯一方法。
  • 对于 iOS 8,请使用 UIBarStyleBlack
  • 谢谢@MatthieuRiegler,我会发通知的。
【解决方案4】:

在 Swift 中,我可以通过以下方式做到这一点:

let tbc : UITabBarController = self.window?.rootViewController as UITabBarController
var moreViewController : UINavigationController = tbc.moreNavigationController

moreViewController.navigationBar.barStyle = UIBarStyle.Black

基本上你对最后一行感兴趣。
这导致标签栏变为白色:

请注意,我没有更改 Info.plist 中的任何内容以实现此结果。
有关更改Navigation Status Bar 的更多信息,请查看此链接: http://www.appcoda.com/customize-navigation-status-bar-ios-7/

【讨论】:

  • 这行得通。但是,它没有使用新的“UIStatusBarStyleLightContent”,我想知道它是否是面向未来的解决方案?还是解决问题!
  • 会是一个很好的答案,但如果您的导航栏被隐藏,则不起作用。
【解决方案5】:

在 viewDidLoad 方法上,这样写:

目标 C

[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent];
[self setNeedsStatusBarAppearanceUpdate];

斯威夫特

UIApplication.shared.statusBarStyle = .lightContent
self.setNeedsStatusBarAppearanceUpdate()

【讨论】:

  • 我很高兴能帮助你,加根
  • 视图控制器正在更新整个应用程序的属性似乎很奇怪 - 解决方案应该针对整个应用程序(位于 AppDelegate 中)或每个视图控制器。
  • 这个方法的swift等效 UIApplication.sharedApplication().setStatusBarStyle(UIStatusBarStyle.LightContent, animated: false)
  • 为了使其工作,必须在目标属性中将基于视图控制器的状态栏外观设置为 NO。我认为这是最好的方法,因为它简单明了。
【解决方案6】:

我敢打赌,您的视图控制器已嵌入到导航控制器中。为避免将导航栏的样式设置为.Black,请使用以下子类:

class YourNavigationController: UINavigationController {
    override func childViewControllerForStatusBarStyle() -> UIViewController? {
        return topViewController
    }
}

【讨论】:

    【解决方案7】:

    斯威夫特:

    let tbc : UITabBarController = self.window?.rootViewController as UITabBarController
    var moreViewController : UINavigationController = tbc.moreNavigationController
    moreViewController.navigationBar.barStyle = UIBarStyle.Black
    

    目标 C:

    将此附加到 controller.m 文件 viewDidLoad 方法:

    [self setNeedsStatusBarAppearanceUpdate].
    

    然后在同一个controller.m 文件中实现此方法:

    - (UIStatusBarStyle) preferredStatusBarStyle { 
        return UIStatusBarStyleLightContent; 
    }
    

    官方文档:

    https://developer.apple.com/library/ios/documentation/UserExperience/Conceptual/TransitionGuide/Bars.html

    我在博客上写的文章:

    http://www.ryadel.com/2015/03/04/xcode-set-status-bar-style-and-color-in-objective-c/

    【讨论】:

      【解决方案8】:

      在要更改状态栏颜色的 ViewController 中

      - (void) viewWillAppear:(BOOL)animated{
          [super viewWillAppear:animated];
          [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleDefault];
      }
      
      - (void) viewWillDisappear:(BOOL)animated{
          [super viewWillDisappear:animated];
          [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent];
      }
      

      【讨论】:

        【解决方案9】:

        Swift 扩展,因为我总是忘记它是如何工作的

        extension UIViewController {
            // utility to set the status bar appearance
            // Note: Make sure "View controller-based status bar appearance" is set to NO in your target settings or this won't work
            func setStatusBarForDarkBackground(dark: Bool) {
                UIApplication.sharedApplication().statusBarStyle = dark ? .LightContent : .Default
                setNeedsStatusBarAppearanceUpdate()
            }
        }
        

        【讨论】:

          【解决方案10】:

          Xcode 10.3,

          在 iPhone 8 12.4 Simulator 中是可以的。

          在 iPhone X 12.4 Simulator 上,我都试过了,不行。

          然后我手动添加,状态栏由时间、电池、蜂窝组成。

          状态栏视图

          
          class StatusBottomView: UIView {
              private var batteryView:BatteryView!
              private var timeLabel:UILabel!
              private var timer:Timer?
          
              override init(frame: CGRect) {
                  super.init(frame: frame)
                  addSubviews()
              }
          
              private func addSubviews() {
                  batteryView = BatteryView()
                  batteryView.tintColor = UIColor.blue
                  addSubview(batteryView)
                  timeLabel = UILabel()
                  timeLabel.textAlignment = .center
                  timeLabel.font = UIFont.systemFont(ofSize: 12)
                  timeLabel.textColor = UIColor.blue
                  addSubview(timeLabel)
                  didChangeTime()
                  addTimer()
              }
          
              override func layoutSubviews() {
                  super.layoutSubviews()
                  let h = frame.size.height
                  let x: CGFloat = 80
                  batteryView.frame.origin = CGPoint(x: ScreenHeight - x - DZMBatterySize.width, y: (h - DZMBatterySize.height) / 2)
                  timeLabel.frame = CGRect(x: x, y: 0, width: 50, height: h)
              }
          
              // MARK: -- Timer
          
              func addTimer() {
                  if timer == nil {
                      timer = Timer.scheduledTimer(timeInterval: 15, target: self, selector: #selector(didChangeTime), userInfo: nil, repeats: true)
                      RunLoop.current.add(timer!, forMode: .common)
                  }
              }
          
          
              func removeTimer() {
                  if timer != nil {
                      timer!.invalidate()
                      timer = nil
                  }
              }
          
          
              @objc func didChangeTime() {
                  timeLabel.text = TimerString("HH:mm")
                  batteryView.batteryLevel = UIDevice.current.batteryLevel
              }
          
          }
          
          

          电池电量查看

          class BatteryView: UIImageView {
          
              override var tintColor: UIColor! {
          
                  didSet{ batteryLevelView.backgroundColor = tintColor }
              }
          
              /// BatteryLevel
              var batteryLevel:Float = 0 {
          
                  didSet{ setNeedsLayout() }
              }
          
              /// BatteryLevelView
              private var batteryLevelView:UIView!
          
              convenience init() {
          
                  self.init(frame: CGRect(x: 0, y: 0, width: DZMBatterySize.width, height: DZMBatterySize.height))
              }
          
          
              override init(frame: CGRect) {
          
                  super.init(frame: CGRect(x: 0, y: 0, width: DZMBatterySize.width, height: DZMBatterySize.height))
          
                  addSubviews()
              }
          
              func addSubviews() {
          
                  batteryLevelView = UIView()
                  batteryLevelView.layer.masksToBounds = true
                  addSubview(batteryLevelView)
          
                  image = UIImage(named: "battery_black")?.withRenderingMode(.alwaysTemplate)
                  tintColor = UIColor.white
              }
          
              override func layoutSubviews() {
                  super.layoutSubviews()
          
                  let spaceW:CGFloat = 1 * (frame.width / DZMBatterySize.width) * HJBatteryLevelViewScale
                  let spaceH:CGFloat = 1 * (frame.height / DZMBatterySize.height) * HJBatteryLevelViewScale
          
                  let batteryLevelViewY:CGFloat = 2.1*spaceH
                  let batteryLevelViewX:CGFloat = 1.4*spaceW
                  let batteryLevelViewH:CGFloat = frame.height - 3.4*spaceH
                  let batteryLevelViewW:CGFloat = frame.width * HJBatteryLevelViewScale
                  let batteryLevelViewWScale:CGFloat = batteryLevelViewW / 100
          
                  var tempBatteryLevel = batteryLevel
          
                  if batteryLevel < 0 {
          
                      tempBatteryLevel = 0
          
                  }else if batteryLevel > 1 {
          
                      tempBatteryLevel = 1
          
                  }
          
                  batteryLevelView.frame = CGRect(x: batteryLevelViewX , y: batteryLevelViewY, width: CGFloat(tempBatteryLevel * 100) * batteryLevelViewWScale, height: batteryLevelViewH)
                  batteryLevelView.layer.cornerRadius = batteryLevelViewH * 0.125
              }
          
          }
          
          
          

          【讨论】:

            猜你喜欢
            • 2014-08-03
            • 1970-01-01
            • 2013-03-29
            • 2018-05-29
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多