Search code examples
iosswiftuiwebview

SWIFT - Loading local CSS file


I am trying to add some local css to my webview but it seems that I have a problem with the css file in my app :

enter image description here

Nothing happens when I try to load the css from the local css file but when I replace '%@' by a online css file it works fine.

Thank you for your help.

import UIKit

class ViewController: UIViewController, UIWebViewDelegate {

    @IBOutlet weak var webview: UIWebView!
    override func viewDidLoad() {
        super.viewDidLoad()
        webview.delegate = self

        let html: String! = "<html><head></head><body><div id=\"postcontent\"><h1>Hello</h1></div></body></html>"

        webview.loadHTMLString(html, baseURL: nil)
    }

    func webViewDidFinishLoad(_ webView: UIWebView){
        let path = Bundle.main.path(forResource: "styles", ofType: "css")

        let javaScriptStr: NSString = "var link = document.createElement('link'); link.href = '%@'; link.rel = 'stylesheet'; document.head.appendChild(link)"
        let javaScripthPath = NSString(format: javaScriptStr, path!)
        webview.stringByEvaluatingJavaScript(from: javaScripthPath as String)
        print(javaScripthPath)
    }
}

Solution

  • Your HTML file is loaded from a string, so it's loaded into a web view that can't access files on the file system (probably due to the Same Origin Policy that browsers implement). It can only access resources similarly injected in via loadHTMLString.

    If you want to use local CSS, load your HTML from a file instead of a string. This will give the web view access to the CSS if it's in the same directory.

    Here is a demo, first, the HTML is now a file.

    enter image description here

    Then, your code can look like this:

    class ViewController: UIViewController, UIWebViewDelegate {
    
        @IBOutlet weak var webview: UIWebView!
        override func viewDidLoad() {
            super.viewDidLoad()
            webview.delegate = self
    
            let path = Bundle.main.path(forResource: "app", ofType: "html")!
            let url = URL(fileURLWithPath: path)
            let request = URLRequest(url: url)
    
            webview.loadRequest(request)
        }
    
        func webViewDidFinishLoad(_ webView: UIWebView){
            let path = Bundle.main.path(forResource: "styles", ofType: "css")!
    
            let javaScriptStr = "var link = document.createElement('link'); link.href = '\(path)'; link.rel = 'stylesheet'; document.head.appendChild(link)"
            webview.stringByEvaluatingJavaScript(from: javaScriptStr)
        }
    }