Search code examples
iosiphonestatusbar

A issue on Changing the Color of the Status Bar when switching apps on iPhone


I want to change the Status Bar color with the specific view controller.

According to StackOverFlow's answers , i achieved it.

There is an issue , when switching apps on iPhone, the color I have set fades, goes back to initial state.

It's OK. Please notice the status bar.

enter image description here

Not OK. Please notice the status bar.

enter image description here I can't figure it out. The code I tried:

  1. set statusBar.backgroundColor,

    UIView *statusBar = [[[UIApplication sharedApplication] valueForKey:@"statusBarWindow"] valueForKey:@"statusBar"];
    if ([statusBar respondsToSelector:@selector(setBackgroundColor:)]) {
         statusBar.backgroundColor = [UIColor redColor ];
    }
    

2. insert subview to statusBar.

 UIView *statusBar = [[[UIApplication sharedApplication] valueForKey:@"statusBarWindow"] valueForKey:@"statusBar"];
 UIView * backgroundColorView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 375, 20) ];
 backgroundColorView.autoresizingMask = UIViewAutoresizingFlexibleWidth;
 backgroundColorView.backgroundColor = [UIColor redColor ];
 [statusBar.subviews.firstObject insertSubview: backgroundColorView atIndex:0];

3. So is to insert layer(CALayer).

And I tried to analyze it with breakpoints.

- When the app is a active, and double-click the Home button to Switch apps, the method is not called - (void)viewWillDisappear:(BOOL)animated . It confuses me a little .

- I try to change the background color of status bar in the Application's method - (void)applicationWillResignActive:(UIApplication *)application, It doesn't work. I don't know why.

While from Github's source code, It's OK through Runtime. My company don't like using Runtime.

Is there some other way without runtime ?

And I don't know how runtime interacts with iPhone's switching apps mode.

The main question is to solve it without runtime. More explain is welcomed. i think it is easy , what do i miss ?

Many thanks in advances.


Solution

  • Answer for Swift 4:

    And it fits the situation of viewControllers managed by navigationViewController

    class ViewController: UIViewController {
    
        let statusBarBgView = { () -> UIView in
            let statusBarWindow: UIView = UIApplication.shared.value(forKey: "statusBarWindow") as! UIView
            let statusBarBgView = UIView(frame: (statusBarWindow.statusBar?.bounds)!)
            return statusBarBgView
        }()
    
    
        override func viewDidLoad() {
            super.viewDidLoad()
            // Do any additional setup after loading the view, typically from a nib.
        }
    
        override func viewWillAppear(_ animated: Bool) {
            super.viewWillAppear(animated)
            UIApplication.shared.statusBarStyle = .lightContent
            let navigationBar = self.navigationController?.navigationBar
            self.statusBarBgView.backgroundColor = UIColor.red
            navigationBar?.superview?.insertSubview(self.statusBarBgView, aboveSubview: navigationBar!)
        }
    
    
        override func viewWillDisappear(_ animated: Bool) {
    
            self.statusBarBgView.removeFromSuperview()
            super.viewWillDisappear(animated)
        }
    
    }
    
    extension UIView {
        var statusBar: UIView? {
            return value(forKey: "statusBar") as? UIView
        }
    }
    

    The Answer Of Objective-C version:

    -(void)viewWillAppear:(BOOL)animated{
        [super viewWillAppear: animated];
        [UIApplication sharedApplication].statusBarStyle=UIStatusBarStyleLightContent;
        UINavigationBar *navigationBar = self.navigationController.navigationBar;
        UIView *statusBar = [[[UIApplication sharedApplication] valueForKey:@"statusBarWindow"] valueForKey:@"statusBar"];
        self.statusBarBgView = [[UIView alloc ] initWithFrame: statusBar.bounds ];
        self.statusBarBgView.backgroundColor = [UIColor redColor ];
        [navigationBar.superview insertSubview: self.statusBarBgView aboveSubview: navigationBar];
    }
    
    - (void)viewWillDisappear:(BOOL)animated {
        [self.statusBarBgView removeFromSuperview ];
        [super viewWillDisappear:animated];
    }
    

    The status bar which shows the OS infos,is UIWindow ,controlled by the OS when in the app switcher window.

    UIView *statusBar = [[[UIApplication sharedApplication] 
    valueForKey:@"statusBarWindow"] valueForKey:@"statusBar"];
    

    So it's OK to adjust the background color of the status bar position by changing the View , when in the app switcher window.