IOS7及更高版本: 为每个视图控制器设置状态栏样式


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

有人有提示吗?

我试过 UIViewControllerBasedStatusBarAppearance

还有

-(UIStatusBarStyle)preferredStatusBarStyle{
return UIStatusBarStyleLightContent;
}

但这些方法都不管用。

93479 次浏览

你试过这个吗?

  1. 在 Info.plist 中将“ View controller-based status bar look”(UIViewControllerBasedStatusBarAppearance)设置为 YES。(YES是默认值,所以您也可以将这个值保留在 plist 中。)

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

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

    - (UIStatusBarStyle) preferredStatusBarStyle {
    return UIStatusBarStyleLightContent;
    }
    

编辑: 这个解决方案在 iOS9上不被推荐。请选择其他答案之一。

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

[UIApplication sharedApplication].statusBarStyle = UIStatusBarStyleBlackTranslucent;

这是因为这个样式的文本颜色在 iOS6及以下版本中是白色的。

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

[UIApplication sharedApplication].statusBarStyle = UIBarStyleBlack;

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

[self.navigationController.navigationBar setBarStyle:UIBarStyleBlack];

这对我来说很有效。

在 viewDidLoad 方法中,放置以下内容:

目标 C

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

斯威夫特

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

在《斯威夫特》一书中,我写道:

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


moreViewController.navigationBar.barStyle = UIBarStyle.Black

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

enter image description here

注意,为了达到这个结果,我没有在 Info.plist中做任何更改。
有关更改 Navigation Status Bar的详情,请参阅以下连结: Http://www.appcoda.com/customize-navigation-status-bar-ios-7/

斯威夫特:

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

目标丙:

将其附加到 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/

在 ViewController 中,您希望更改状态栏的颜色

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


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

快速扩展,因为我总是忘记这是如何工作的

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()
}
}

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

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

Xcode 10.3,

在 iPhone812.4模拟器中,这是可以的。

在 iPhoneX12.4模拟器中,我尝试了以上所有方法,但都不行。

然后我手动添加它,状态栏包括时间,电池,手机。

11

StatusBarView


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
}


}


BatteryLevelView

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
}


}