我正在使用Xcode 8.0 beta 4。
在以前的版本中,UIViewController具有设置状态栏样式的方法
public func preferredStatusBarStyle() -> UIStatusBarStyle
然而,我发现它改为"只能变换"在Swift 3中。
public var preferredStatusBarStyle: UIStatusBarStyle { get }
如何提供在我的UIViewController中使用的样式?
答案 0 :(得分:438)
这是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。
版本7之前的iOS,已弃用的方法
Apple has deprecated this,因此将来会被删除。使用上面的方法,以便在下一个iOS版本发布时不必重写它。
如果您的应用程序支持在您的应用程序Info.plist
中,请将“查看基于控制器的状态栏外观”设置为NO。
在appDelegate.swift
,didFinishLaunchingWithOptions
功能中,添加:
UIApplication.shared.statusBarStyle = .lightContent
答案 1 :(得分:135)
对于愿意理解过去几年中存在的不同方法背后的逻辑的人来说,这篇文章完好无损。同时,从 Xcode 10,Swift 4.2 first approach is deprecated开始,不再受支持(如果您尝试使用 将不会生效)。仍然会提供您的信息,以便更好地理解Plist.info
标志和自定义练习背后的原因。
了解自定义状态栏外观的两种方法非常重要。它们是不同的,不应混合。
在info.plist中,您可以找到或创建一个名为
的密钥 View controller-based status bar appearance
并将其设置为否。
它做什么?它基本上建立了一个设置,表明在您的应用程序中,状态栏外观不是由每个视图控制器单独定义。理解这一点非常重要。这意味着对于所有屏幕,您可以为整个应用设置统一设置。有两种设置: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
方法,它允许完全自定义导航栏+状态栏外观)。它可能会导致您的应用被拒绝。但也许你很幸运。如果你是,在某些复杂的情况下(比如嵌套,子导航和视图控制器的层次结构),这可能是自定义状态栏外观的唯一或至少不那么麻烦的方法(例如,使其透明)< / p>
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")
}
}
}
答案 2 :(得分:128)
您可以尝试覆盖返回的值,而不是设置它。该方法声明为{get},因此只需提供一个getter:
override var preferredStatusBarStyle: UIStatusBarStyle {
return .lightContent
}
如果您有条件地设置此选项,则需要致电setNeedsStatusBarAppearanceUpdate()
,以便在您准备就绪时为更改设置动画
答案 3 :(得分:99)
Swift 3&amp; 4,iOS 10&amp; 11,Xcode 9&amp; 10 强>
对我来说,这种方法不起作用:
override var preferredStatusBarStyle: UIStatusBarStyle {
return .lightContent
}
当我习惯了每个视图控制器时,但这很有效:
在文件info.list中,添加行View controller-based status bar appearance
并设置为NO
接下来在appdelegate:
UIApplication.shared.statusBarStyle = .lightContent
答案 4 :(得分:26)
如果您想将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
的{{1}},而不是UINavigationController
其中包含的statusBarStyle
ViewControllers
。
希望这可以帮助那些没有成功接受答案的人!
答案 5 :(得分:25)
您需要在Info.plist文件中添加以下密钥:
Fill
,布尔值设置为 Rectangle
在appdelegate类中,在返回之前使用Fill
方法。
View controller-based status bar appearance
根据要求更改NO
和didFinishLaunchingWithOptions
。
答案 6 :(得分:24)
如果要在视图出现后随时更改状态栏样式,可以使用:
在文件info.list中添加行:查看基于控制器的状态栏外观并将其设置为是
var viewIsDark = Bool()
func makeViewDark() {
viewIsDark = true
setNeedsStatusBarAppearanceUpdate()
}
func makeViewLight() {
viewIsDark = false
setNeedsStatusBarAppearanceUpdate()
}
override var preferredStatusBarStyle: UIStatusBarStyle {
if viewIsDark {
return .lightContent
} else {
return .default
}
}
答案 7 :(得分:13)
您也可以在故事板中执行此操作
答案 8 :(得分:8)
首先,您需要添加一行密钥:<body ng-app="mainApp">
<div ng-controller="myController">
<select>
<option ng-repeat="person in persons.data">{{person}}</option>
</select>
</div>
</body>
和值View controller-based status bar appearance
到NO
文件。之后,在控制器中添加2个功能,只有控制器才能生效:
Info.plist
答案 9 :(得分:6)
处理导航栏时,状态栏文本颜色似乎有一个小问题。
如果您希望.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
当条形样式为黑色时,它会侦听被覆盖的变量。希望这有助于某人:)
答案 10 :(得分:6)
Swift 3
在Info.plist中添加一行名为“查看基于控制器的状态栏外观”并将其值设置为No
。
class YourViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
UIApplication.shared.statusBarStyle = .lightContent //or .default
setNeedsStatusBarAppearanceUpdate()
}
}
答案 11 :(得分:5)
Xcode 8.3.1,Swift 3.1
在info.plist中创建一个新条目&#34;查看基于控制器的状态栏外观&#34;将它设置为&#34; NO&#34;。
打开AppDelegate.swift并在&#34; didFinishLaunchingWithOptions&#34;中添加这些行。方法:
application.statusBarStyle = .lightContent
答案 12 :(得分:5)
对于希望在以下平台上更改所有视图控制器状态栏的用户:iOS 11,Swfit 4解决方案非常简单。
1) Info.plist添加:
基于视图控制器的状态栏外观->否
2) XCode slect项目的左侧> 目标>选择您的项目>在General>部署信息下>选择状态栏样式:浅
如果您只想更改一个viewcontroller 的状态栏,请在viewDidLoad上添加:
override var preferredStatusBarStyle : UIStatusBarStyle {
return .lightContent
}
答案 13 :(得分:5)
要为在https://stackoverflow.com/a/40066798/2082851的 PRAVEEN 的答案添加更多详细信息,我想提供我的实现。它支持灵活性来自定义每个控制器的状态栏。
总体而言,我们将创建一个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
}
}
}
}
UINavigationController
对于UINavigationController
,这是一种特殊情况,您可以采用以下任一解决方案:
由于UINavigationController是NSObject
并继承自ObjectiveC
,因此它的方法是message dispatch
,您可以覆盖它们。
extension UINavigationController {
open override var preferredStatusBarStyle: UIStatusBarStyle {
return topViewController?.preferredStatusBarStyle ?? .default
}
}
UINavigationController
子类如果您已经有一个自定义UINavigationController
(通常需要控制更多要求),那么这是最适合您的解决方案。
final class NavigationController: UINavigationController {
override var preferredStatusBarStyle: UIStatusBarStyle {
return topViewController?.preferredStatusBarStyle ?? super.preferredStatusBarStyle
}
}
答案 14 :(得分:4)
要添加@Krunal https://stackoverflow.com/a/49552326/4697535
如果您使用的是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
}
}
}
答案 15 :(得分:4)
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
}
答案 16 :(得分:4)
以下是关于状态栏样式更改的Apple Guidelines/Instruction。
如果要设置状态栏样式,应用程序级别,请在UIViewControllerBasedStatusBarAppearance
文件中将NO
设置为.plist
。并在您的appdelegate
&gt; didFinishLaunchingWithOptions
添加以下ine(以编程方式,您可以从app delegate中执行此操作)。
目标C
[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent animated:YES];
<强>夫特强>
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
application.statusBarStyle = .lightContent
return true
}
如果您要在视图控制器级别设置状态栏样式,请按照以下步骤操作:
UIViewControllerBasedStatusBarAppearance
文件中将YES
设置为.plist
。 在viewDidLoad添加功能 - setNeedsStatusBarAppearanceUpdate
覆盖视图控制器中的preferredStatusBarStyle。
目标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的值。
答案 17 :(得分:3)
override var preferredStatusBarStyle: UIStatusBarStyle {
return .lightContent
}
这对我有用:)我的导航控制器中嵌入了导航控制器,而导航栏却隐藏了。我想在应用程序中的某些视图上设置状态栏灯。
答案 18 :(得分:3)
这对我有用
将View controller-based status bar
外观设置为plist中的 NO ,然后在UIViewController
viewDidAppear
中添加以下行
UIApplication.shared.setStatusBarStyle(UIStatusBarStyle.lightContent, animated: true)
答案 19 :(得分:3)
swift 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
}
}
答案 20 :(得分:2)
您可以使用名为“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
})
}
}
答案 21 :(得分:2)
Swift 4 +
表示白色状态栏文字:
navigationController.navigationBar.barStyle = .blackTranslucent
答案 22 :(得分:2)
这些答案中的大多数都是相同的东西,但是当使用深色背景时,它们实际上都没有为我解决启动屏幕的问题。
我在info.plist
中用以下内容解决了这个问题,该内容产生了一个浅色的状态栏。
<key>UIStatusBarStyle</key>
<string>UIStatusBarStyleLightContent</string>
答案 23 :(得分:2)
答案 24 :(得分:1)
如果要在整个应用程序中更改状态栏。
不要忘记info.plist的更改
运行项目并进行检查。
我在Swift 5和Xcode 10.2中的项目
答案 25 :(得分:1)
如果您使用模式演示,则需要设置:
viewController.modalPresentationCapturesStatusBarAppearance = true
答案 26 :(得分:0)
使用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
}
}
答案 27 :(得分:0)
请在您的info.plist中添加以下行,然后只有您才能实现
“基于视图控制器的状态栏外观=否”
并将以下代码段添加到您的代码中,然后查看输出
unset spring_profiles_active
答案 28 :(得分:0)
对于目标C,只需在应用程序中添加此行didFinishLaunch方法
UIApplication.sharedApplication.statusBarStyle = UIStatusBarStyleLightContent;
答案 29 :(得分:0)
如果收到警告:在iOS 9.0中不建议使用'statusBarStyle'设置:使用-[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
答案 30 :(得分:0)
在iOS 13中,您可以使用.darkContent
UIStatusBarStyle
属性显示暗状态栏
答案 31 :(得分:0)
如果您仍然无法根据方法更改状态栏样式
override var preferredStatusBarStyle: UIStatusBarStyle {
return .lightContent
}
您可以尝试使用此方法:
override viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
navigationController?.navigationBar.barStyle = .black
}
答案 32 :(得分:0)
我得到了:
覆盖var必须与其封闭类型
一样可访问
通过添加public
来解决此问题:
override public var preferredStatusBarStyle: UIStatusBarStyle {
get {
return .lightContent
}
}
在Swift3 iOS10上。
答案 33 :(得分:0)
我也在为此而苦苦挣扎,因此,如果要呈现FULLSCREEN模态视图控制器,请确保将.modalPresentationStyle
设置为.fullscreen
,然后在呈现的视图控制器上,只需覆盖{{1 }}到.preferredStatusBarStyle
。
所以:
.lightContent
在自定义视图控制器上,覆盖状态栏样式:
let navigationController = UINavigationController(rootViewController: viewController)
navigationController.modalPresentationStyle = .fullScreen // <=== make sure to set navigation modal presentation style
present(navigationController, animated: true, completion: nil)
答案 34 :(得分:-1)
Swift 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
}