15

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?

funkenstrahlen
  • 3,032
  • 2
  • 28
  • 40

3 Answers3

2

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];
konradholub
  • 133
  • 9
0

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

pkamb
  • 33,281
  • 23
  • 160
  • 191
David Yang Liu
  • 1,170
  • 2
  • 10
  • 19
  • Thank you for your response. I know all this. **Setting the status bar style for my own view controller works perfectly fine**. However I do not know how to make `Safari View Controller` us the correct status bar style. This is an Apple class and not under my direct control. – funkenstrahlen Feb 02 '16 at 09:17
  • [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent]; doesn't work for you ? adding it before the call? – David Yang Liu Feb 02 '16 at 09:20
  • Setting `UIApplication.sharedApplication().statusBarStyle = UIStatusBarStyle.Default` right before calling the SVC does not change anything. This is because I use `View Controller based status bar color` set to `YES`, because my app requires that. I also can not override `preferredStatusBarStyle` for the `Safari View Controller` as it is not my class. – funkenstrahlen Feb 02 '16 at 09:31
0

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)
Eugene Babich
  • 1,271
  • 15
  • 25