Injecting a local css into UIWebView
Solution 1
I also had trouble doing this.
I was trying to load an HTML file from a server and change the styling using a local CSS file.
At first I used
[webView loadRequest:reqObj];
And when it hit - (void)webViewDidFinishLoad:(UIWebView *)webView
i was trying to push the CSS file as a child to 'head':
- (void)webViewDidFinishLoad:(UIWebView *)webView
{
NSString *path = [[NSBundle mainBundle] bundlePath];
NSString *cssPath = [path stringByAppendingPathComponent:@"style.css"];
NSString *js = [NSString stringWithFormat:@"var cssChild = document.createElement('link');"
"cssChild = 'text/css';"
"cssChild = 'stylesheet';"
"cssChild = '%@';", cssPath];
js = [NSString stringWithFormat:@"%@ document.getElementsByTagName('head')[0].appendChild(cssChild);", js];
[webView stringByEvaluatingJavaScriptFromString:js];
}
So... it didn't work...
then i tried
NSString *path = [[NSBundle mainBundle] bundlePath];
NSURL *baseURL = [NSURL fileURLWithPath:path];
[webView loadHTMLString:htmlString baseURL:baseURL];
(I copied the HTML string into htmlString) and then, inside - (void)webViewDidFinishLoad:(UIWebView *)webView
I injected the CSS as in the code above. And it worked!
But... my HTML file is stored in a remote server and I didn't have the HTML string, so I used
NSString* myFile = [NSString stringWithFormat:@"http://blablabla.com/file.html"];
NSString* myFileURLString = [myFile stringByReplacingPercentEscapesUsingEncoding:NSASCIIStringEncoding];
NSData *myFileData = [[NSData alloc] initWithContentsOfURL:[NSURL URLWithString:myFileURLString]];
NSString* myFileHtml = [[[NSString alloc] initWithData:myFileData encoding:NSASCIIStringEncoding] autorelease];
To get the HTML. Now, I have the raw HTML text inside ' myFileHtml '. I now use
NSString *path = [[NSBundle mainBundle] bundlePath];
NSURL *baseURL = [NSURL fileURLWithPath:path];
[webView loadHTMLString:myFileHtml baseURL:baseURL];
And catching the response in ' webViewDidFinishLoad ', injecting my CSS file into it and it worked :)
Maybe there's another, more elegant, solution to this problem, but this is what I came up with...
Hope it helped.
Solution 2
cssNode.href = '%@';", cssPath];
The line above fails because it tries to fetch the file from the webserver. Using something like:
cssNode.href = 'file://%@';", cssPath];
accesses the local file system. You can use Safari's developer mode to inspect the iPhone simulator and see whether file is found and loaded.
I eventually ended up implementing inline stylesheets instead of linking to stylesheet. Here's the code that works for me
NSError *error;
NSString *css = [[NSString alloc] initWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"stylesheet" ofType:@"css"] encoding:NSASCIIStringEncoding error:&error];
css = [css stringByReplacingOccurrencesOfString:@"\n" withString:@" "]; // js dom inject doesn't accept line breaks, so remove them
NSString *js = [NSString stringWithFormat:@"var styleNode = document.createElement('style');"
"styleNode.type = 'text/css';"
"styleNode.innerHTML = ' %@ ';", css];
js = [NSString stringWithFormat:@"%@document.getElementsByTagName('head')[0].appendChild(styleNode);", js];
[_webView stringByEvaluatingJavaScriptFromString:js];
Solution 3
I ran into this while looking for an answer to the same question. I'm loading an HTML page from a web server into a UIWebView. The HTML already has lots of CSS, appropriate for web viewing. In my case I wanted to display:none a few irrelevant div's.
I didn't want to store the HTML locally then load from the file, so I came up with another solution, conceptually similar to others here but more to my tastes. This is Swift 3. Have this run after the page loads, but before it's displayed:
let css = "#someDiv {display:none;} #otherDiv {display:none;} .someClass {display:none;}"
let js = "var sheet = document.createElement('style');sheet.innerHTML = \"\(css)\";document.body.appendChild(sheet);"
webView.stringByEvaluatingJavaScript(from: js)
Gal
Updated on June 04, 2022Comments
-
Gal almost 2 years
I'm trying to "inject" a local css file into downloaded xhtml file.
I found many examples of how to do it, but it just doesn't work for me...
Here is my code:
- (void)webViewDidFinishLoad:(UIWebView *)webView { NSString *path = [[NSBundle mainBundle] bundlePath]; NSString *cssPath = [path stringByAppendingPathComponent:@"test.css"]; NSString *js = [NSString stringWithFormat:@"var cssNode = document.createElement('link');" "cssNode.type = 'text/css';" "cssNode.rel = 'stylesheet';" "cssNode.href = '%@';", cssPath]; js = [NSString stringWithFormat:@"%@document.getElementsByTagName('head')[0].appendChild(cssNode);", js]; //m_webview is a member [m_webView stringByEvaluatingJavaScriptFromString:js]; }
What am I doing wrong here?
Thanks,
-
Gal over 12 yearsthanks, but it still looks the same. I wonder, how can I tell if 'stringByEvaluatingJavaScriptFromString' worked or failed?
-
Gal over 12 yearsThanks! That did work. I just had to add '[myFileData release];'