15
votes

My app uses a dark navigation bar color. Therefore I set the status bar color to white (so it has a nice contrast).

red navigation bar with white status bar

I did this by setting the barStyle to black (to make the status bar white) and also setting the barTint to my dark red color. Works perfectly.

I present a SafariViewController like this:

func openWebsite(urlString: String) {
    if let url = NSURL(string: urlString) {
        let svc = SFSafariViewController(URL: url)
        svc.delegate = self
        self.presentViewController(svc, animated: true, completion: nil)
    }
}

However the status bar of the presented SafariViewController still is white. This is a problem because the SVC navigation bar has the default white transparent iOS default style. So the status bar is basically invisible.

safari view controller with white status bar color

How can I fix that?

3

3 Answers

2
votes

You can achieve that by wrapping SFSafariViewController with subclassed UINavigationController.

BlackStatusBarNavigationController.h

@interface BlackStatusBarNavigationController : UINavigationController
@end

BlackStatusBarNavigationController.h

@interface BlackStatusBarNavigationController ()

@end

@implementation BlackStatusBarNavigationController

- (UIStatusBarStyle)preferredStatusBarStyle {
    return UIStatusBarStyleDefault;
}

@end

Use like this:

UINavigationController *navigationController = [[BlackStatusBarNavigationController alloc] initWithRootViewController:viewController];
navigationController.navigationBarHidden = YES;

[self presentViewController:navigationController animated:YES completion:nil];
0
votes

There are 2 ways you can override preferredStatusBarStyle in your viewControllers and return the one you want

- (UIStatusBarStyle)preferredStatusBarStyle
{
    return UIStatusBarStyleLightContent;
}

override func preferredStatusBarStyle() -> UIStatusBarStyle {
    return .Default
}

or you can set it manually with

[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent];

UIApplication.sharedApplication().setStatusBarHidden(false, withAnimation: UIStatusBarAnimation.None)

how ever for setting it through sharedApplicaion you will need to add this in to your plist "View controller-based status bar appearance" to NO enter image description here

0
votes

If you want to set background color of status bar for iOS 13+, you can try to set it force like this.

import UIKit
import SafariServices

class CustomSFSafariViewController: SFSafariViewController {
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(true)

        if #available(iOS 13.0, *) {
            UIApplication.shared.statusBarView?.backgroundColor = .purple
        }

        setNeedsStatusBarAppearanceUpdate()
    }
}


extension UIApplication {
    @available(iOS 13.0, *)
    var statusBarView: UIView? {
        let tag = 3848245
        
        let keyWindow = connectedScenes
            .map({$0 as? UIWindowScene})
            .compactMap({$0})
            .first?.windows.first
        
        if let statusBar = keyWindow?.viewWithTag(tag) {
            return statusBar
        } else {
            let height = keyWindow?.windowScene?.statusBarManager?.statusBarFrame ?? .zero
            let statusBarView = UIView(frame: height)
            statusBarView.tag = tag
            statusBarView.layer.zPosition = 999999
            
            keyWindow?.addSubview(statusBarView)
            return statusBarView
        }
    }
}

There are few useful properties for customization of SFSafariViewController which you can use:

  • preferredControlTintColor (color of toolbar items)
  • preferredBarTintColor (color of toolbar)

P.S. don't forget to use CustomSFSafariViewController instead of SFSafariViewController. You can do it like this.

let safariViewController = CustomSFSafariViewController(url: url)