我正在使用Xcode 8.0 beta 4。
在之前的版本中,UIViewController有方法可以设置状态栏样式。
public func preferredStatusBarStyle() -> UIStatusBarStyle
然而,我发现在Swift 3中它变成了一个 "仅获取变量"。
public var preferredStatusBarStyle: UIStatusBarStyle { get }
我该如何为我的UIViewController提供样式?
我正在使用Xcode 8.0 beta 4。
在之前的版本中,UIViewController有方法可以设置状态栏样式。
public func preferredStatusBarStyle() -> UIStatusBarStyle
然而,我发现在Swift 3中它变成了一个 "仅获取变量"。
public var preferredStatusBarStyle: UIStatusBarStyle { get }
我该如何为我的UIViewController提供样式?
为了对 PRAVEEN 在 https://dev59.com/7lkT5IYBdhLWcg3wV-GZ#40066798 的回答添加更多细节,我想提供我的实现方式。它支持 灵活性,可以自定义每个控制器的状态栏。
总体上,我们将创建一个名为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
,其方法是消息分发
,因此您可以覆盖它们。
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
}
}
首先,您需要添加一个键为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
}
在处理导航栏时,状态栏文本颜色似乎存在一些小问题。
如果您想要将 .plist 条目“View controller-based status bar appearance”设置为 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
在info.plist中创建一个新的条目“View controller-based status bar appearance”,将其设置为“NO”。
打开AppDelegate.swift并在“didFinishLaunchingWithOptions”方法中添加以下行:
application.statusBarStyle = .lightContent
Swift 3
在 Info.plist 中添加一行名为“View controller-based status bar appearance”的内容,并将其值设置为 No
。
class YourViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
UIApplication.shared.statusBarStyle = .lightContent //or .default
setNeedsStatusBarAppearanceUpdate()
}
}
在@Krunal的出色回答中,我想补充一些内容。https://dev59.com/7lkT5IYBdhLWcg3wV-GZ#49552326
如果您正在使用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
}
}
}
Swift 4+
如果需要白色状态栏文字:
navigationController.navigationBar.barStyle = .blackTranslucent
这里是关于状态栏样式更改的苹果指南/说明书。
如果您想设置应用程序级别的状态栏样式,请在您的.plist
文件中将UIViewControllerBasedStatusBarAppearance
设置为NO
。并且在您的appdelegate
>didFinishLaunchingWithOptions
中添加以下行(您可以从应用程序委托以编程方式执行此操作)。
Objective C
[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent animated:YES];
Swift
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
application.statusBarStyle = .lightContent
return true
}
.plist
文件中将 UIViewControllerBasedStatusBarAppearance
设置为 YES
,仅在 UIViewController 级别需要设置状态栏样式时才需执行此步骤。在 viewDidLoad 中添加函数 - setNeedsStatusBarAppearanceUpdate
覆盖您的视图控制器中的 preferredStatusBarStyle。
Objective C
- (void)viewDidLoad
{
[super viewDidLoad];
[self setNeedsStatusBarAppearanceUpdate];
}
- (UIStatusBarStyle)preferredStatusBarStyle
{
return UIStatusBarStyleLightContent;
}
Swift
override func viewDidLoad() {
super.viewDidLoad()
self.setNeedsStatusBarAppearanceUpdate()
}
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
}
var preferredStatusBarStyle: UIStatusBarStyle = .lightContent
- Anbu.Karthik