import UIKit import WebKit class ViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() // Configure the web view for JavaScript injection configureWebView() } private func configureWebView() { let css = """ html, body { overflow-x: hidden; } body { background-color: #333333; line-height: 1.5; color: white; padding: 10; font-weight: 600; font-family: -apple-system; } """ // Make CSS into single liner let cssString = css.components(separatedBy: .newlines).joined() // Create JavaScript that loads the CSS let javaScript = """ var element = document.createElement('style'); element.innerHTML = '\(cssString)'; document.head.appendChild(element); """ // Create user script that inject the JavaScript after the HTML finishes loading let userScript = WKUserScript(source: javaScript, injectionTime: .atDocumentEnd, forMainFrameOnly: true) // Set user script to a configuration object and load it into the webView let userContentController = WKUserContentController() userContentController.addUserScript(userScript) let configuration = WKWebViewConfiguration() configuration.userContentController = userContentController let webView = WKWebView(frame: CGRect.zero, configuration: configuration) // Show web view on screen view.addSubview(webView) webView.layer.cornerRadius = 20.0 webView.layer.masksToBounds = true webView.translatesAutoresizingMaskIntoConstraints = false NSLayoutConstraint.activate([ webView.topAnchor.constraint(equalTo: view.layoutMarginsGuide.topAnchor, constant: 20.0), webView.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 20.0), webView.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -20.0), webView.bottomAnchor.constraint(equalTo: view.layoutMarginsGuide.bottomAnchor, constant: -20.0), ]) // Load content to webView DispatchQueue.global().async { let link = "https://swiftsenpai.com/wp-content/uploads/2022/01/plainHtmlSample.html" guard let url = URL(string: link), let htmlContent = try? String(contentsOf: url, encoding: .utf8) else { assertionFailure("Fail to get agreement HTML") return } DispatchQueue.main.async { // Prepend `<meta>` viewport element to the HTML so that it will scale correctly in a mobile device let metaTag = "<meta name=\"viewport\" content=\"user-scalable=no, width=device-width\">" let html = "\(metaTag)\(htmlContent)" // Load HTML string to web view in main thread webView.loadHTMLString(html, baseURL: nil) } } } }