DEV Community

Ceri-anne
Ceri-anne

Posted on

10

Dynamically adding CSS to webviews in Swift

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

 

Sentry mobile image

Mobile Vitals: A first step to Faster Apps

Slow startup times, UI hangs, and frozen frames frustrate users—but they’re also fixable. Mobile Vitals help you measure and understand these performance issues so you can optimize your app’s speed and responsiveness. Learn how to use them to reduce friction and improve user experience.

Read the guide →

Top comments (3)

Collapse
 
danielsalare profile image
Daniel Salazar

Great!! Thanks

Collapse
 
ben profile image
Ben Halpern

Thanks for this, just what I needed.

Collapse
 
farhanaxmustafa profile image
Farhana

This really helped me learn what evaluateJavaScript() does! Thank you

Sentry mobile image

Improving mobile performance, from slow screens to app start time

Based on our experience working with thousands of mobile developer teams, we developed a mobile monitoring maturity curve.

Read more

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay