如何在wkwebview中为某些指定的URL加载css文件?

问题描述 投票:-4回答:2

我有一个WKWebView。该网页从CDN加载其大部分css文件。但是,有这个经常使用的大型css文件,我想把它放在应用程序Bundle中,以便webview加载更快。有谁知道如何从捆绑加载?

我不想插入css文件。我想将一些css文件请求重定向到我的本地文件URL。

Swift版本会很棒。

谢谢。

ios swift wkwebview
2个回答
1
投票

按如下所示创建style.css文件,然后将其拖放到项目目录中

@font-face {
    font-family: "Titillium Web";
    font-weight: normal;
    src: url("TitilliumWeb-Regular.ttf")
}

@font-face {
    font-family: "Titillium Web";
    font-style: italic;
    src: url("TitilliumWeb-Italic.ttf")
}

@font-face {
    font-family: "Titillium Web";
    font-weight: bold;
    src: url("TitilliumWeb-Bold.ttf")
}
body {
    margin: 0;
    font-family: "Titillium Web";
    font-weight: normal;
    font-size: 13pt;
}

在UIViewController的viewDidLoad()中添加以下源代码

override func viewDidLoad() {
    super.viewDidLoad()

    let html = """
    "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. <b>Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</b>
    <br>
    <i>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</i>
    <br>
    Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur."
"""

    let htmlStart = "<HTML><HEAD><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, shrink-to-fit=no\"></HEAD><BODY>"
    let htmlEnd = "</BODY></HTML>"
    let htmlString = "\(htmlStart)\(html)\(htmlEnd)"
    webView.loadHTMLString(htmlString, baseURL: Bundle.main.bundleURL)
    self.view.addSubview(webView)
  }

如下创建WKWebView对象并运行应用程序,它将加载内容。

  lazy var webView: WKWebView = {
    guard
      let path = Bundle.main.path(forResource: "style", ofType: "css"),
      let cssString = try? String(contentsOfFile: path).components(separatedBy: .newlines).joined()
      else {
        return WKWebView()
    }

    let source = """
    var style = document.createElement('style');
    style.innerHTML = '\(cssString)';
    document.head.appendChild(style);
    """

    let userScript = WKUserScript(source: source,
                                  injectionTime: .atDocumentEnd,
                                  forMainFrameOnly: true)

    let userContentController = WKUserContentController()
    userContentController.addUserScript(userScript)

    let configuration = WKWebViewConfiguration()
    configuration.userContentController = userContentController

    let webView = WKWebView(frame: self.view.frame,
                            configuration: configuration)
    return webView
  }()

enter image description here


0
投票

您可以将html预加载到String,在一些样式标记内注入本地CSS的内容,最后在WKWebView中显示已修改的字符串。

下面您将看到一个有效的解决方案,您只需要在项目中拖动一个名为inject.css的文件。此文件包含要应用的样式。

确保您有一个名为webView的WKWebView和一个连接到插座的按钮,以使以下解决方案有效(此解决方案可能需要一些重构):

import UIKit
import WebKit

class ViewController: UIViewController {
  @IBOutlet weak var webView: WKWebView!

  @IBAction func loadStuffTapped(_ sender: Any) {

    injectCssAndShow(url: "https://www.wikipedia.org/")

  }

  // this one loads the css from your bundle
  func loadCss()->String? {
    if let filepath = Bundle.main.path(forResource: "inject", ofType: "css") {
      do {
        let contents = try String(contentsOfFile: filepath)
        print(contents)
        return contents
      } catch {
        // contents could not be loaded
      }
    } else {
      // inject.css not found!
    }
    return nil
  }

// this (kind of bloated...) function loads the orignal html, injects your css and shows the modified version inside of your WKWebview
  func injectCssAndShow(url: String) {

    let request = NSMutableURLRequest(url: NSURL(string: url)! as URL,
                                      cachePolicy: .useProtocolCachePolicy,
                                      timeoutInterval: 10.0)
    request.httpMethod = "GET"

    let session = URLSession.shared
    let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
      if (error != nil) {
        print(error as Any)
      } else {
        let htmlString = String(decoding: data ?? Data(), as: UTF8.self)

        DispatchQueue.main.async {

          let result = htmlString.range(of: "<title>",
                                        options: NSString.CompareOptions.literal,
                                        range: htmlString.startIndex..<htmlString.endIndex,
                                        locale: nil)

          if let range = result {
            let start = range.lowerBound
            let injection = self.loadCss() ?? ""
            let modifiedHtml = "\(htmlString[htmlString.startIndex..<start]) <style>\(injection)</style> \(htmlString[start..<htmlString.endIndex])"
            self.webView.loadHTMLString(modifiedHtml, baseURL: URL.init(string: url))
          }
        }
      }
    })

    dataTask.resume()

  }
}

Animation of posted solution

© www.soinside.com 2019 - 2024. All rights reserved.