This article was first published here https://www.ceri-anne.co.uk/dynamically-add-css-to-webviews-in-swift
This week, I needed to figure out how to dynamically add css to a webView in iOS and it was much easier than I thought it would be.
All you need to do is make use of the webViewdidFinish function in the WKNavigationDelegate and evaluateJavaScript
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) { | |
let css = "body { background-color : #ff0000 }" | |
let js = "var style = document.createElement('style'); style.innerHTML = '\(css)'; document.head.appendChild(style);" | |
webView.evaluateJavaScript(js, completionHandler: nil) | |
} |
This code will change the background colour of the webpage you are displaying to red.
To show how this works, I created a simple sample app with a series of buttons with colour choices on:
Clicking on any of the buttons takes you to a webView which displays www.google.co.uk but the background colour of the webpage changes depending on the button chosen. So if you click on green you're taken to this page:
To do this, in the ViewController I added an IBAction which performs the segue when a button is tapped. The button text is then passed through to the WebViewController:
import UIKit | |
class ViewController: UIViewController { | |
@IBAction func buttonTapped(_ sender: Any) { | |
performSegue(withIdentifier: "showWebView", sender: sender) | |
} | |
override func prepare(for segue: UIStoryboardSegue, sender: Any?) { | |
if let button = sender as? UIButton, let destination = segue.destination as? WebViewController { | |
destination.colour = button.titleLabel?.text | |
} | |
} | |
} |
In the WebViewController there is a function getHexColour which determines the hex code colour based on the colour set in the segue.
Then in webViewDidFinish I created the css and JavaScript and applied that to the webView using the evaluateJavascript function:
import UIKit | |
import WebKit | |
class WebViewController: UIViewController, WKNavigationDelegate { | |
var webView: WKWebView! | |
var colour: String? | |
override func loadView() { | |
webView = WKWebView() | |
webView.navigationDelegate = self | |
view = webView | |
} | |
override func viewDidLoad() { | |
super.viewDidLoad() | |
let url = URL(string: "https://www.google.co.uk")! | |
webView.load(URLRequest(url: url)) | |
} | |
func getHexColour() -> String? { | |
if let colour = colour { | |
switch colour { | |
case "Red" : return "#FF0000" | |
case "Green" : return "#00FF00" | |
case "Blue" : return "#0000FF" | |
default : return nil | |
} | |
} | |
return nil | |
} | |
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) { | |
guard let colour = getHexColour() else { | |
return | |
} | |
let css = "body { background-color : \(colour) }" | |
let js = "var style = document.createElement('style'); style.innerHTML = '\(css)'; document.head.appendChild(style);" | |
webView.evaluateJavaScript(js, completionHandler: nil) | |
} | |
} |
Here's a link to the sample project code: https://github.com/Ceri-anne/WebViewCss
Top comments (3)
Great!! Thanks
Thanks for this, just what I needed.
This really helped me learn what evaluateJavaScript() does! Thank you