在UIWebView/WKWebView中将CSS插入到加载的HTML中

col*_*ole 31 objective-c uiwebview ios wkwebview

我成功地获取HTML内容并显示到我的UIWebView中.

但是想要通过添加外部CSS文件来自定义内容.我只能改变文字和字体的大小.我尝试了所有可能的解决方案来进行更改,但它不起作用 - 它没有显示任何变化.

以下是我的代码

HTMLNode* body = [parser body];
HTMLNode* mainContentNode = [body  findChildWithAttribute:@"id" matchingName:@"main_content" allowPartial:NO];
NSString *pageContent = [NSString stringWithFormat:@"%@%@", cssString, contentHtml];
        [webView loadHTMLString:pageContent baseURL:[NSURL URLWithString:@"http://www.example.org"]];

-(void)webViewDidFinishLoad:(UIWebView *)webView1{
    int fontSize = 50;
    NSString *font = [[NSString alloc] initWithFormat:@"document.getElementsByTagName('body')[0].style.webkitTextSizeAdjust= '%d%%'", fontSize];
    NSString *fontString = [[NSString alloc] initWithFormat:@"document.getElementById('body').style.fontFamily=\"helvetica\""];

    [webView1 stringByEvaluatingJavaScriptFromString:fontString];
    [webView1 stringByEvaluatingJavaScriptFromString:font];
}
Run Code Online (Sandbox Code Playgroud)

请帮助我在我的视图中获取css样式表.

joe*_*ern 54

你可以这样做:

- (void)webViewDidFinishLoad:(UIWebView *)webView {
    NSString *cssString = @"body { font-family: Helvetica; font-size: 50px }"; // 1
    NSString *javascriptString = @"var style = document.createElement('style'); style.innerHTML = '%@'; document.head.appendChild(style)"; // 2
    NSString *javascriptWithCSSString = [NSString stringWithFormat:javascriptString, cssString]; // 3
    [webView stringByEvaluatingJavaScriptFromString:javascriptWithCSSString]; // 4
}
Run Code Online (Sandbox Code Playgroud)

这段代码的作用:

// 1:定义包含所有CSS声明的字符串

// 2:定义一个javascript字符串,用于创建新的<style>HTML DOM元素并将CSS声明插入其中.实际上插入是在下一步完成的,现在只有%@占位符.我这样做是为了防止线路变得太长,但是第2步和第3步可以一起完成.

// 3:组合2个字符串

// 4:在UIWebView中执行javascript

为此,您的HTML必须有一个<head></head>元素.

编辑:

您还可以从本地css文件加载css字符串(在本例中名为"styles.css").只需使用以下内容替换步骤// 1:

NSString *path = [[NSBundle mainBundle] pathForResource:@"styles" ofType:@"css"];
NSString *cssString = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:nil];
Run Code Online (Sandbox Code Playgroud)

作为另一种选择,你可以只注入一个加载CSS文件的<link>元素<head>:

- (void)webViewDidFinishLoad:(UIWebView *)webView {
    NSString *path = [[NSBundle mainBundle] pathForResource:@"styles" ofType:@"css"];
    NSString *javascriptString = @"var link = document.createElement('link'); link.href = '%@'; link.rel = 'stylesheet'; document.head.appendChild(link)";
    NSString *javascriptWithPathString = [NSString stringWithFormat:javascriptString, path];
    [webView stringByEvaluatingJavaScriptFromString:javascriptWithPathString];
}
Run Code Online (Sandbox Code Playgroud)

此解决方案最适合大型CSS文件.不幸的是,它不适用于远程HTML文件.只有当您想要将CSS插入已下载到应用程序的HTML中时,才能使用此选项.

更新:WKWebView/Swift 3.x

当您使用WKWebView注入时,<link>由于WKWebView安全设置,元素不起作用.

您仍然可以将css作为字符串注入.在代码中创建CSS字符串//1或将其放在本地文件中//2.要知道,与WKWebView你必须做在注射WKNavigationDelegatewebView(_:didFinish:)方法:

func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
    insertCSSString(into: webView) // 1
    // OR
    insertContentsOfCSSFile(into: webView) // 2
}

func insertCSSString(into webView: WKWebView) {
    let cssString = "body { font-size: 50px; color: #f00 }"
    let jsString = "var style = document.createElement('style'); style.innerHTML = '\(cssString)'; document.head.appendChild(style);"
    webView.evaluateJavaScript(jsString, completionHandler: nil)
}

func insertContentsOfCSSFile(into webView: WKWebView) {
    guard let path = Bundle.main.path(forResource: "styles", ofType: "css") else { return }
    let cssString = try! String(contentsOfFile: path).trimmingCharacters(in: .whitespacesAndNewlines)
    let jsString = "var style = document.createElement('style'); style.innerHTML = '\(cssString)'; document.head.appendChild(style);"
    webView.evaluateJavaScript(jsString, completionHandler: nil)
}
Run Code Online (Sandbox Code Playgroud)

  • 我认为webView:didFinish:navigation:不是最好的注入时间. (3认同)
  • 有用。但我必须将 cssString 包装成 **single** 行。`"""` 的多行不起作用。 (3认同)
  • 如果您将 wkWebView 设置为使用:“wkWebView.loadHTMLString(html, baseURL: Bundle.main.resourceURL)”,则插入 `&lt;link&gt;` 也可以在 WKWebView 中使用: (2认同)

Ame*_*kic 11

由于UIWebView在iOS 12中已弃用,因此我只回答WKWebView。我已经实现了CSS加载,如接受的答案中所述。问题在于,有时可以看到从没有CSS的HTML过渡到带有CSS的HTML。
我认为更好的方法是使用WKUserScript像这样注入CSS:

lazy var webView: WKWebView = {
    guard let path = Bundle.main.path(forResource: "style", ofType: "css") else {
        return WKWebView()
    }

    let cssString = try! String(contentsOfFile: path).components(separatedBy: .newlines).joined()
    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: .zero,
                            configuration: configuration)
    return webView
}()
Run Code Online (Sandbox Code Playgroud)

您可以在此博客文章中了解有关此方法的更多信息