iOS 7 及更高版本:为每个视图控制器设置状态栏样式
Posted
技术标签:
【中文标题】iOS 7 及更高版本:为每个视图控制器设置状态栏样式【英文标题】:iOS 7 and later: set status bar style per view controller 【发布时间】:2013-10-01 13:54:40 【问题描述】:我尝试了许多方法来设置状态栏样式(默认或 lightcontent),但无法让它在每个视图控制器的基础上工作。我只能为整个应用设置状态栏样式。
有人有提示吗?
我试过UIViewControllerBasedStatusBarAppearance
和
-(UIStatusBarStyle)preferredStatusBarStyle
return UIStatusBarStyleLightContent;
但这些方法不起作用。
【问题讨论】:
***.com/questions/18979837/cant-hide-ios-7-status-bar/… 并确保导航栏不与状态栏重叠...... 我使用了一个小技巧(以及控制可见/隐藏状态)——我决定将其发布为 pod 'UIViewController+ODStatusBar' (cocoapods.org/pods/UIViewController+ODStatusBar) 这只是 Apple 随机将 iOS 版本的行为更改为下一个版本的几十个 API 之一,并且由于某种原因,开发人员还没有完全反抗。您必须修改您的实现以适应您的应用运行的 iOS 版本,并在每次构建新版本时对其进行测试。 【参考方案1】:你试过了吗?
在 Info.plist 中将“基于控制器的状态栏外观”(UIViewControllerBasedStatusBarAppearance
) 设置为 YES
。 (YES
是默认值,因此您也可以将此值保留在 plist 之外。)
在你的 viewDidLoad 方法中,调用[self setNeedsStatusBarAppearanceUpdate]
。
实现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
【讨论】:
以上是关于iOS 7 及更高版本:为每个视图控制器设置状态栏样式的主要内容,如果未能解决你的问题,请参考以下文章
iOS 7 中的视图移动到导航栏上方,但在 iOS 6 中可以正常工作
iOS 在 iPhone 6 及更高版本上设置导航项标题视图框架故障
我应该怎么做才能使这个菜单栏在 Internet Explorer 7 及更高版本中正常工作?