Search code examples
iosswiftuibuttonuiappearancesfsafariviewcontroller

How to change tint of navigation bar in SafariViewController when setting UIButton appearance in AppDelegate


I am trying to change the tint of the navigation bar in a SFSafariViewController when UIButton.appearance() is being set in the AppDelegate.

For example:

AppDelegate

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {

    // Here is the global setting that I want to override in the 
       SafariViewController
    UIButton.appearance().tintColor = UIColor.green
}

SFSafariViewController

override func viewDidLoad() {
    super.viewDidLoad()

    // This will change the toolbar tint but not the Done button or the 
       website name in the "navigation" section
    preferredControlTintColor = UIColor.white
}

However, both the Done button and the color of the website name are still green.

I also tried making overrides for objects in the App Delegate. None of them worked.

App Delegate (also in didFinishLaunchingWithOptions)

// These are attempts to override the tint set above. None seem to work.
UIButton.appearance(whenContainedInInstancesOf: [SFSafariViewController.self]).tintColor = UIColor.white
UIBarButtonItem.appearance(whenContainedInInstancesOf: [SFSafariViewController.self]).tintColor = UIColor.white
UINavigationBar.appearance(whenContainedInInstancesOf: [SFSafariViewController.self]).tintColor = UIColor.white

I also attempted setting the tint of the view in the Safari View Controller itself, but it does not tint the navigation bar.

SFSafariViewController (also in viewDidLoad)

// This can be seen by bringing up an alert like in a peek
view.tintColor = UIColor.purple

This was written in Swift 3.0 and tested in Xcode 8.1.

I have posted a sample project on github.

Any help would be greatly appreciated. Thank you.

(Colors were chosen for testing purposes.)


Solution

  • I think the only way that I found is to use the same code that you have written in AppDelegate but at appropriate positions.

    On presenting the safari controller

    //Just before presenting the Safari Controller, change the color to red. It will make the Done button color to red.
    UIButton.appearance().tintColor = UIColor.red
    let controller = StyledSafariViewController(url: appleUrl)
    present(controller, animated: true, completion: nil)
    

    And in the viewWillDisappear method of SafariController class

    Again make your button color to global

    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
    
        //resetting your button color
        UIButton.appearance().tintColor = UIColor.green
    }