我正在使用Xcode 8.0 beta 4。
在以前的版本中,UIViewController具有设置状态栏样式的方法
public func preferredStatusBarStyle() -> UIStatusBarStyle
但是,我发现它在Swift 3中改为“Get ONLY变量”。
public var preferredStatusBarStyle: UIStatusBarStyle { get }
如何在我的UIViewController中提供使用的样式?
这是iOS 7及更高版本的首选方法
在应用程序的Info.plist
中,将“查看基于控制器的状态栏外观”设置为YES。
Override preferredStatusBarStyle
in each of your view controllers。例如:
override var preferredStatusBarStyle: UIStatusBarStyle {
return .lightContent
}
如果preferredStatusBarStyle
根据视图控制器内部更改的内容返回不同的首选状态栏样式(例如,滚动位置或显示的图像是否为暗),那么当该状态发生变化时,您将需要调用setNeedsStatusBarAppearanceUpdate()
。
如果使用导航控制器并且希望使用每个视图控制器的首选状态栏样式,请参阅https://stackoverflow.com/a/41026726/1589422。
iOS 7之前的版本,不推荐使用的方法
Apple has deprecated this,所以它将来会被删除。使用上面的方法,以便在下一个iOS版本发布时不必重写它。
如果您的应用程序将支持在您的应用程序的Info.plist
中,请将“查看基于控制器的状态栏外观”设置为NO。
在appDelegate.swift
,didFinishLaunchingWithOptions
函数,添加:
UIApplication.shared.statusBarStyle = .lightContent
斯威夫特3
在Info.plist中添加一行称为“基于视图控制器的状态栏外观”,并将其值设置为No
。
class YourViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
UIApplication.shared.statusBarStyle = .lightContent //or .default
setNeedsStatusBarAppearanceUpdate()
}
}
处理导航栏时,状态栏文本颜色似乎有一个小问题。
如果您希望.plist条目将基于控制器的状态栏外观设置为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
当条形样式为黑色时,它会侦听被覆盖的变量。希望这有助于某人:)
Xcode 8.3.1,Swift 3.1
application.statusBarStyle = .lightContent
对于希望在所有视图控制器上更改状态栏的人:iOS 11,Swift 4解决方案非常简单。
1)Info.plist add:
查看基于控制器的状态栏外观 - >否
2)XCode选择项目的左侧>目标>选择项目>常规>部署信息>选择状态栏样式:光
如果只想为一个viewcontroller更改状态栏,请在viewDidLoad上添加:
override var preferredStatusBarStyle : UIStatusBarStyle {
return .lightContent
}
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
}
这是关于状态栏样式变化的Apple Guidelines/Instruction。
如果要设置状态栏样式,应用程序级别,然后在UIViewControllerBasedStatusBarAppearance
文件中将NO
设置为.plist
。并在您的appdelegate
> didFinishLaunchingWithOptions
添加以下ine(以编程方式,您可以从app委托执行此操作)。
目标C.
[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent animated:YES];
迅速
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
application.statusBarStyle = .lightContent
return true
}
如果要设置状态栏样式,请在视图控制器级别执行以下步骤:
UIViewControllerBasedStatusBarAppearance
文件中将YES
设置为.plist
。setNeedsStatusBarAppearanceUpdate
目标C.
- (void)viewDidLoad
{
[super viewDidLoad];
[self setNeedsStatusBarAppearanceUpdate];
}
- (UIStatusBarStyle)preferredStatusBarStyle
{
return UIStatusBarStyleLightContent;
}
迅速
override func viewDidLoad() {
super.viewDidLoad()
self.setNeedsStatusBarAppearanceUpdate()
}
override var preferredStatusBarStyle: UIStatusBarStyle {
return .lightContent
}
根据状态栏样式设置级别设置.plist的值。
加入@Krunal https://stackoverflow.com/a/49552326/4697535的伟大asnwer
如果你使用UINavigationController
,preferredStatusBarStyle
将对UIViewController
没有影响。
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
}
}
}
这对我有用
将View controller-based status bar
外观设置为plist中的NO然后在UIViewController
viewDidAppear
中添加以下行
UIApplication.shared.setStatusBarStyle(UIStatusBarStyle.lightContent, animated: true)
迅捷3
如果在Info.plist中查看基于控制器的状态栏外观= YES
然后对所有NavigationController使用此扩展
extension UINavigationController
{
override open var preferredStatusBarStyle: UIStatusBarStyle {
return .lightContent
}
}
如果没有UINavigationController,只有UIViewController,那么使用下面的代码:
extension UIViewController
{
override open var preferredStatusBarStyle: UIStatusBarStyle {
return .lightContent
}
}
override var preferredStatusBarStyle: UIStatusBarStyle {
return .lightContent
}
这对我有用:)我的导航控制器嵌入在我的视图控制器中,隐藏了导航栏。我想在应用程序的某些视图上设置状态栏指示灯。
对于愿意理解过去几年中存在的不同方法背后的逻辑的人来说,本文保持不变。同时,从Xcode 10开始,不再支持Swift 4.2 first approach is deprecated(即如果你尝试使用它也不会生效)。它仍然提供给您的信息,以便更好地理解Plist.info
旗帜和定制实践背后的原因。
了解自定义状态栏外观的两种方法非常重要。它们是不同的,不应该混合。
在info.plist中,您可以找到或创建一个名为的密钥
View controller-based status bar appearance
并将其设置为NO。
它能做什么?它基本上建立了一个设置,表明在您的应用程序中,状态栏外观不是由每个视图控制器单独定义的。理解这一点非常重要。这意味着您可以为所有屏幕设置整个应用程序的统一设置。有两种设置:default
,白色背景上的黑色文字,或lightContent
,黑色背景上的白色文字。
要设置其中一个(所有屏幕都有一个设置):
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
application.statusBarStyle = .lightContent // .default
return true
}
这样,您无需在每个视图控制器上重新建立此设置。但是,您始终可以使用此方法自动更改外观。
这是相反的。要使其工作,请继续info.plist并设置
View controller-based status bar appearance
是的
这样,每当打开一个新的视图控制器时,如果在每个需要的UIViewController
实例中插入此实现,则会单独设置状态栏样式:
override var preferredStatusBarStyle: UIStatusBarStyle {
return .lightContent // .default
}
您与第一个相同,为状态栏设置暗或浅样式,为每个视图控制器设置个别。
UIKit在两种情况下获取此属性:
setNeedsStatusBarAppearanceUpdate()
。在后一种情况下,您有资格通过以下代码操纵状态栏外观:
var isDark = false {
didSet {
setNeedsStatusBarAppearanceUpdate()
}
}
override var preferredStatusBarStyle: UIStatusBarStyle {
return isDark ? .lightContent : .default
}
func toggleAppearance() {
isDark.toggle()
}
然后,每当您调用toggleAppearance()
时,将触发状态栏样式更改。
有一个hack允许直接访问状态栏:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
if let statusBar = UIApplication.shared.value(forKey: "statusBar") as? UIView {
statusBar.backgroundColor = UIColor.blue
}
return true
}
为什么破解?如果您需要状态栏颜色而不是黑色或白色,则使用未记录的API。你使用KVC获得statusBar
对象并设置其背景颜色。你用这种方式获得的对象是UIStatusBar
,它源自UIView
,因此自然支持backgroundColor
属性。这是脏的,不合法的方式,但到目前为止,它是为状态栏设置自定义颜色的唯一方法(不考虑UINavigationBar
方法,它允许完全自定义导航栏+状态栏外观)。它可能会导致您的应用被拒绝。但也许你很幸运。如果你是,在某些复杂情况下(如嵌套,子导航和视图控制器的层次结构),这可能是自定义状态栏外观的唯一或至少不那么麻烦的方法(例如,使其透明)
Xcode 10 +,Swift 4.2
没有其他选择:开发人员应该让每个视图控制器定义状态栏外观,方法是将标志设置为YES(或省略此操作,因为默认情况下为YES)并遵循上述说明。
奖金
您可能(虽然不鼓励)在复杂环境中使用基于Hack的解决方案,以便在任何阶段自动更改状态栏外观。颜色方面,以下扩展方法完全按照常规方法完成。您可以根据自己的需要进行调整。
extension UIViewController {
func setStatusBarStyle(_ style: UIStatusBarStyle) {
if let statusBar = UIApplication.shared.value(forKey: "statusBar") as? UIView {
statusBar.backgroundColor = style == .lightContent ? UIColor.black : .white
statusBar.setValue(style == .lightContent ? UIColor.white : .black, forKey: "foregroundColor")
}
}
}
如果要更改整个应用程序中的状态栏。
不要忘记info.plist的变化
运行您的项目并检查它。
我在swift 5和Xcode 10.2中的项目
Swift 4+
对于白色状态栏文本:
navigationController.navigationBar.barStyle = .blackTranslucent
iOS 11.2
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
UINavigationBar.appearance().barStyle = .black
return true
}
您可以使用名为“shouldStatusBarDark”的bool属性来切换状态栏颜色。您还可以更新其值以在滚动时更改状态栏颜色。
var shouldStatusBarDark = false {
didSet {
setNeedsStatusBarAppearanceUpdate()
}
}
override var preferredStatusBarStyle: UIStatusBarStyle {
return shouldStatusBarDark ? .default : .lightContent
}
func scrollViewDidScroll(_ scrollView: UIScrollView) {
let offSetY = scrollView.contentOffset.y
if offSetY > 50 {
UIView.animate(withDuration: 0.4, animations: {
self.navView.alpha = 1
self.shouldStatusBarDark = true
})
} else {
UIView.animate(withDuration: 0.4, animations: {
self.navView.alpha = 0
self.shouldStatusBarDark = false
})
}
}
这些答案中的大多数都是重新散列的,但在使用深色背景时,它们都没有真正解决我的启动画面问题。
我在info.plist
中使用以下内容来解决这个问题,这会产生一个轻巧的状态栏。
<key>UIStatusBarStyle</key>
<string>UIStatusBarStyleLightContent</string>
如果您收到警告:在iOS 9.0中不推荐使用'statusBarStyle'的Setter:使用 - [UIViewController preferredStatusBarStyle],然后将状态栏设置为亮或暗使用以下代码:
//To set the status bar to white
self.navigationController?.navigationBar.barStyle = .black //or .blackTranslucent
//To set the status bar to black
self.navigationController?.navigationBar.barStyle = .default
这不会使您的navBar更改它纯粹指示样式,因此相应地更改状态栏。
NB。您需要确保在info.plist中设置。
View controller-based status bar appearance to YES
我得到了:
覆盖var必须与其封闭类型一样可访问
通过添加public
来解决这个问题:
override public var preferredStatusBarStyle: UIStatusBarStyle {
get {
return .lightContent
}
}
在Swift3 iOS10上。
对于目标C,只需在应用程序的didFinishLaunch方法中添加此行
UIApplication.sharedApplication.statusBarStyle = UIStatusBarStyleLightContent;
使用WebkitView
Swift 9.3 iOS 11.3
import UIKit
import WebKit
class ViewController: UIViewController, WKNavigationDelegate, WKUIDelegate {
@IBOutlet weak var webView: WKWebView!
var hideStatusBar = true
override func loadView() {
let webConfiguration = WKWebViewConfiguration()
webView = WKWebView(frame: .zero, configuration: webConfiguration)
webView.uiDelegate = self
view = webView
}
override func viewDidLoad() {
super.viewDidLoad()
self.setNeedsStatusBarAppearanceUpdate()
let myURL = URL(string: "https://www.apple.com/")
let myRequest = URLRequest(url: myURL!)
UIApplication.shared.statusBarView?.backgroundColor = UIColor.red
webView.load(myRequest)
}
}
extension UIApplication {
var statusBarView: UIView? {
return value(forKey: "statusBar") as? UIView
}
}
请将以下行添加到info.plist中,然后才能实现
“查看基于控制器的状态栏外观=否”
并将以下代码段添加到您的代码中并查看输出
UIApplication.shared.statusBarStyle = .lightContent
UIApplication.shared.statusBarStyle = .default
您可以尝试覆盖返回的值,而不是设置它。该方法声明为{get},因此只需提供一个getter:
override var preferredStatusBarStyle: UIStatusBarStyle {
return .lightContent
}
如果您有条件地设置此项,则需要调用setNeedsStatusBarAppearanceUpdate()
,以便在准备好后对其进行动画处理
斯威夫特3
要在应用程序中设置相同的导航栏外观,可以在AppDelegate.swift中执行此操作:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
setupNavigationBarAppearence()
return true
}
private func setupNavigationBarAppearence(){
let navigationBarAppearace = UINavigationBar.appearance()
navigationBarAppearace.isTranslucent = false
//nav bar color
navigationBarAppearace.barTintColor = UIColor.primaryColor()
//SETS navbar title string to white
navigationBarAppearace.titleTextAttributes = [NSForegroundColorAttributeName: UIColor.white]
//Makes the batery icon an any other icon of the device to white.
navigationBarAppearace.barStyle = .black
}
Swift 3&4,iOS 10和11,Xcode 9和10 对我来说,这种方法不起作用:
override var preferredStatusBarStyle: UIStatusBarStyle {
return .lightContent
}
当我习惯每个视图控制器,但这工作:
View controller-based status bar appearance
并设置为NO
UIApplication.shared.statusBarStyle = .lightContent
如果你想将statusBar
的颜色更改为白色,对于UINavigationController
中包含的所有视图,请在AppDelegate
中添加:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
UINavigationBar.appearance().barStyle = .blackOpaque
return true
}
这段代码:
override var preferredStatusBarStyle: UIStatusBarStyle {
return .lightContent
}
不适用于UIViewControllers
中包含的UINavigationController
,因为编译器会查找statusBarStyle
的UINavigationController
,而不是statusBarStyle
包含的ViewControllers
。
希望这能帮助那些没有成功接受答案的人!
您需要在Info.plist文件中添加以下键:
View controller-based status bar appearance
,布尔值设置为NO
在你的appdelegate类中,在返回之前在didFinishLaunchingWithOptions
方法中。
let statusBar: UIView = UIApplication.shared.value(forKey: "statusBar") as! UIView
if statusBar.responds(to:#selector(setter: UIView.backgroundColor)) {
statusBar.backgroundColor = UIColor.red
}
UIApplication.shared.statusBarStyle = .lightContent
根据要求改变backgroundColor
和statusBarStyle
。
如果要在视图出现后随时更改状态栏样式,可以使用以下命令:
var viewIsDark = Bool()
func makeViewDark() {
viewIsDark = true
setNeedsStatusBarAppearanceUpdate()
}
func makeViewLight() {
viewIsDark = false
setNeedsStatusBarAppearanceUpdate()
}
override var preferredStatusBarStyle: UIStatusBarStyle {
if viewIsDark {
return .lightContent
} else {
return .default
}
}
您也可以在故事板中执行此操作
您必须为每个导航控制器执行此操作。但是,该导航控制器下的任何视图都会将所有视图的状态栏样式/颜色更改为您刚刚选择的那个。我发现这个选项更好,因为你可以立即看到你的结果,而不必在每个视图控制器中添加额外的代码行。
(在所有Swift项目中使用Xcode 8.3.3完成)
第一步,您需要添加一行密钥: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
}