preferredStatusBarStyle isn't called

2019-01-01 16:35发布

I followed this thread to override -preferredStatusBarStyle, but it isn't called. Are there any options that I can change to enable it? (I'm using XIBs in my project.)

20条回答
梦寄多情
2楼-- · 2019-01-01 17:17

Note that when using the self.navigationController.navigationBar.barStyle = UIBarStyleBlack; solution

be sure to go to your plist and set "View controller-based status bar appearance" to YES. If its NO it will not work.

查看更多
人气声优
3楼-- · 2019-01-01 17:18

If anyone is using a Navigation Controller and wants all of their navigation controllers to have the black style, you can write an extension to UINavigationController like this in Swift 3 and it will apply to all navigation controllers (instead of assigning it to one controller at a time).

extension UINavigationController {

    override open func viewDidLoad() {
        super.viewDidLoad()

        self.navigationBar.barStyle = UIBarStyle.black
    }

}
查看更多
余生请多指教
4楼-- · 2019-01-01 17:19

If your viewController is under UINavigationController.

Subclass UINavigationController and add

override var preferredStatusBarStyle: UIStatusBarStyle {
    return topViewController?.preferredStatusBarStyle ?? .default
}

ViewController's preferredStatusBarStyle will be called.

查看更多
何处买醉
5楼-- · 2019-01-01 17:20

If someone run into this problem with UISearchController. Just create a new subclass of UISearchController, and then add code below into that class:

override func preferredStatusBarStyle() -> UIStatusBarStyle {
    return .LightContent
}
查看更多
冷夜・残月
6楼-- · 2019-01-01 17:21

Here's my method for solving this.

Define a protocol called AGViewControllerAppearance.

AGViewControllerAppearance.h

#import <Foundation/Foundation.h>

@protocol AGViewControllerAppearance <NSObject>

@optional

- (BOOL)showsStatusBar;
- (BOOL)animatesStatusBarVisibility;
- (UIStatusBarStyle)preferredStatusBarStyle;
- (UIStatusBarAnimation)prefferedStatusBarAnimation;

@end

Define a category on UIViewController called 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

Now, it's time to say that you're view controller is implementing the AGViewControllerAppearance protocol.

Example:

@interface XYSampleViewController () <AGViewControllerAppearance>

... the rest of the interface

@end

Of course, you can implement the rest of the methods (showsStatusBar, animatesStatusBarVisibility, prefferedStatusBarAnimation) from the protocol and UIViewController+Upgrade will do the proper customization based on the values provided by them.

查看更多
回忆,回不去的记忆
7楼-- · 2019-01-01 17:22

For anyone using a UINavigationController:

The UINavigationController does not forward on preferredStatusBarStyle calls to its child view controllers. Instead it manages its own state - as it should, it is drawing at the top of the screen where the status bar lives and so should be responsible for it. Therefor implementing preferredStatusBarStyle in your VCs within a nav controller will do nothing - they will never be called.

The trick is what the UINavigationController uses to decide what to return for UIStatusBarStyleDefault or UIStatusBarStyleLightContent. It bases this on its UINavigationBar.barStyle. The default (UIBarStyleDefault) results in the dark foreground UIStatusBarStyleDefault status bar. And UIBarStyleBlack will give a UIStatusBarStyleLightContent status bar.

TL;DR:

If you want UIStatusBarStyleLightContent on a UINavigationController use:

self.navigationController.navigationBar.barStyle = UIBarStyleBlack;
查看更多
登录 后发表回答