我遵循这个线程重写-preferredStatusBarStyle,但它没有被调用。 有什么选项我可以改变来启用它吗?(我在我的项目中使用xib。)
当前回答
如果你的viewController在UINavigationController下面。
子类UINavigationController并添加
override var preferredStatusBarStyle: UIStatusBarStyle {
return topViewController?.preferredStatusBarStyle ?? .default
}
ViewController的preferredStatusBarStyle将被调用。
其他回答
如果有人正在使用一个导航控制器,并希望他们所有的导航控制器都有黑色风格,你可以在Swift 3中写一个扩展到UINavigationController,它将应用于所有的导航控制器(而不是一次分配给一个控制器)。
extension UINavigationController {
override open func viewDidLoad() {
super.viewDidLoad()
self.navigationBar.barStyle = UIBarStyle.black
}
}
如果有人在使用UISearchController时遇到这个问题。 只需要创建一个UISearchController的新子类,然后将下面的代码添加到这个类中:
override func preferredStatusBarStyle() -> UIStatusBarStyle {
return .LightContent
}
我的应用程序使用了所有三个:UINavigationController, UISplitViewController, UITabBarController,因此这些似乎都接管了对状态栏的控制,并将导致preferedStatusBarStyle不为他们的孩子被调用。要覆盖此行为,您可以创建一个扩展,就像前面提到的其他答案一样。这是一个扩展,这三个,在Swift 4。希望苹果对这类事情能更清楚些。
extension UINavigationController {
open override var childViewControllerForStatusBarStyle: UIViewController? {
return self.topViewController
}
open override var childViewControllerForStatusBarHidden: UIViewController? {
return self.topViewController
}
}
extension UITabBarController {
open override var childViewControllerForStatusBarStyle: UIViewController? {
return self.childViewControllers.first
}
open override var childViewControllerForStatusBarHidden: UIViewController? {
return self.childViewControllers.first
}
}
extension UISplitViewController {
open override var childViewControllerForStatusBarStyle: UIViewController? {
return self.childViewControllers.first
}
open override var childViewControllerForStatusBarHidden: UIViewController? {
return self.childViewControllers.first
}
}
编辑:针对Swift 4.2 API更改的更新
extension UINavigationController {
open override var childForStatusBarStyle: UIViewController? {
return self.topViewController
}
open override var childForStatusBarHidden: UIViewController? {
return self.topViewController
}
}
extension UITabBarController {
open override var childForStatusBarStyle: UIViewController? {
return self.children.first
}
open override var childForStatusBarHidden: UIViewController? {
return self.children.first
}
}
extension UISplitViewController {
open override var childForStatusBarStyle: UIViewController? {
return self.children.first
}
open override var childForStatusBarHidden: UIViewController? {
return self.children.first
}
}
这是我解决这个问题的方法。
定义一个名为AGViewControllerAppearance的协议。
AGViewControllerAppearance.h
#import <Foundation/Foundation.h>
@protocol AGViewControllerAppearance <NSObject>
@optional
- (BOOL)showsStatusBar;
- (BOOL)animatesStatusBarVisibility;
- (UIStatusBarStyle)preferredStatusBarStyle;
- (UIStatusBarAnimation)prefferedStatusBarAnimation;
@end
在UIViewController上定义一个名为Upgrade的类别。
UIViewController+Upgrade.h
#import <UIKit/UIKit.h>
@interface UIViewController (Upgrade)
//
// Replacements
//
- (void)upgradedViewWillAppear:(BOOL)animated;
@end
UIViewController+Upgrade.m
#import "UIViewController+Upgrade.h"
#import <objc/runtime.h>
#import "AGViewControllerAppearance.h" // This is the appearance protocol
@implementation UIViewController (Upgrade)
+ (void)load
{
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wselector"
Method viewWillAppear = class_getInstanceMethod(self, @selector(viewWillAppear:));
#pragma clang diagnostic pop
Method upgradedViewWillAppear = class_getInstanceMethod(self, @selector(upgradedViewWillAppear:));
method_exchangeImplementations(viewWillAppear, upgradedViewWillAppear);
}
#pragma mark - Implementation
- (void)upgradedViewWillAppear:(BOOL)animated
{
//
// Call the original message (it may be a little confusing that we're
// calling the 'same' method, but we're actually calling the original one :) )
//
[self upgradedViewWillAppear:animated];
//
// Implementation
//
if ([self conformsToProtocol:@protocol(AGViewControllerAppearance)])
{
UIViewController <AGViewControllerAppearance> *viewControllerConformingToAppearance =
(UIViewController <AGViewControllerAppearance> *)self;
//
// Status bar
//
if ([viewControllerConformingToAppearance respondsToSelector:@selector(preferredStatusBarStyle)])
{
BOOL shouldAnimate = YES;
if ([viewControllerConformingToAppearance respondsToSelector:@selector(animatesStatusBarVisibility)])
{
shouldAnimate = [viewControllerConformingToAppearance animatesStatusBarVisibility];
}
[[UIApplication sharedApplication] setStatusBarStyle:[viewControllerConformingToAppearance preferredStatusBarStyle]
animated:shouldAnimate];
}
if ([viewControllerConformingToAppearance respondsToSelector:@selector(showsStatusBar)])
{
UIStatusBarAnimation animation = UIStatusBarAnimationSlide;
if ([viewControllerConformingToAppearance respondsToSelector:@selector(prefferedStatusBarAnimation)])
{
animation = [viewControllerConformingToAppearance prefferedStatusBarAnimation];
}
[[UIApplication sharedApplication] setStatusBarHidden:(! [viewControllerConformingToAppearance showsStatusBar])
withAnimation:animation];
}
}
}
@end
现在,是时候说你的视图控制器正在实现AGViewControllerAppearance协议。
例子:
@interface XYSampleViewController () <AGViewControllerAppearance>
... the rest of the interface
@end
当然,你可以实现其余的方法(showsStatusBar, animatesStatusBarVisibility, prefereredstatusbaranimation)从协议和UIViewController+升级将做适当的 基于它们提供的值进行定制。
对于任何仍然与此斗争的人来说,这个简单的扩展在swift中应该为您解决这个问题。
extension UINavigationController {
override open var childForStatusBarStyle: UIViewController? {
return self.topViewController
}
}
推荐文章
- 自定义dealloc和ARC (Objective-C)
- 调整UITableView的大小以适应内容
- 在代码中为UIButton设置一个图像
- NSRange从Swift Range?
- UICollectionView中的单元格间距
- 我如何在我的iOS应用程序中每n分钟得到一个后台位置更新?
- 如何使用iOS创建GUID/UUID
- 禁用所呈现视图控制器的交互式撤销
- 点击按钮时如何打开手机设置?
- 如何使用UIVisualEffectView来模糊图像?
- 如何修复UITableView分隔符在iOS 7?
- 故事板中的自定义单元格行高设置没有响应
- 在Swift中使用自定义消息抛出错误/异常的最简单方法?
- 如何在Swift中获得唯一的设备ID ?
- 复制文本到剪贴板与iOS