Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Insert CSS into loaded HTML in UIWebView / WKWebView

I am successfully able to get HTML content and display into my UIWebView.

But want to customize the content by adding an external CSS file. I can only change the size of text and font. I tried every possible solution to make changes but it does not work - it shows no changes.

Below is my code

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]; } 

Please help me get the css stylesheet in my view.

like image 542
cole Avatar asked Oct 14 '15 10:10

cole


People also ask

How do I import HTML into WKWebView?

Load Local HTML File to a WKWebViewlet myUrl = myProjectBundle. url(forResource: "my-html-file", withExtension: "html")! where: my-html-file – is the name of HTML file you want to load into WKWebView from your App Bundle.

What is the difference between UIWebView and WKWebView?

Unlike UIWebView, which does not support server authentication challenges, WKWebView does. In practical terms, this means that when using WKWebView, you can enter site credentials for password-protected websites.

How do I display HTML data in swift webView?

How to load a HTML string into a WKWebView or UIWebView: loadHTMLString() If you want to load resources from a particular place, such as JavaScript and CSS files, you can set the baseURL parameter to any URL .

Is WKWebView the same as Safari?

WKWebView. WKWebView was introduced in iOS 8 allowing app developers to implement a web browsing interface similar to that of mobile Safari. This is due, in part, to the fact that WKWebView uses the Nitro Javascript engine, the same engine used by mobile Safari.


1 Answers

You can do it like this:

- (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 } 

What this code does:

// 1 : Define a string that contains all the CSS declarations

// 2 : Define a javascript string that creates a new <style> HTML DOM element and inserts the CSS declarations into it. Actually the inserting is done in the next step, right now there is only the %@ placeholder. I did this to prevent the line from becoming too long, but step 2 and 3 could be done together.

// 3 : Combine the 2 strings

// 4 : Execute the javascript in the UIWebView

For this to work, your HTML has to have a <head></head> element.

EDIT:

You can also load the css string from a local css file (named "styles.css" in this case). Just replace step //1 with the following:

NSString *path = [[NSBundle mainBundle] pathForResource:@"styles" ofType:@"css"]; NSString *cssString = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:nil]; 

As another option you can just inject a <link> element to the <head> that loads the CSS file:

- (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]; } 

This solution works best for large CSS files. Unfortunately it does not work with remote HTML files. You can only use this when you want to insert CSS into HTML that you have downloaded to your app.

UPDATE: WKWebView / Swift 3.x

When you are working with a WKWebView injecting a <link> element does not work because of WKWebView's security settings.

You can still inject the css as a string. Either create the CSS string in your code //1 or put it in a local file //2. Just be aware that with WKWebView you have to do the injection in WKNavigationDelegate's webView(_:didFinish:) method:

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) } 
like image 51
joern Avatar answered Sep 19 '22 14:09

joern