Вставьте CSS в загруженный HTML в UIWebView/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];
}
Пожалуйста, помогите мне получить таблицу стилей css на мой взгляд.
Ответы
Ответ 1
Вы можете сделать это следующим образом:
- (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
}
Что делает этот код:
//1: Определить строку, содержащую все объявления CSS
//2: Определите строку javascript, которая создает новый элемент HTML DOM <style>
и вставляет в него объявления CSS. Фактически вставка выполняется на следующем шаге, прямо сейчас есть только %@
placeholder. Я сделал это, чтобы линия не стала слишком длинной, но шаги 2 и 3 можно было сделать вместе.
//3: Объедините 2 строки
//4: Выполнить javascript в UIWebView
Чтобы это работало, ваш HTML должен иметь элемент <head></head>
.
РЕДАКТИРОВАТЬ:
Вы также можете загрузить строку css из локального файла css (с именем "styles.css" в этом случае). Просто замените step//1 следующим:
NSString *path = [[NSBundle mainBundle] pathForResource:@"styles" ofType:@"css"];
NSString *cssString = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:nil];
В качестве другого варианта вы можете просто ввести элемент <link>
в <head>
который загружает файл CSS:
- (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];
}
Это решение лучше всего подходит для больших файлов CSS. К сожалению, он не работает с удаленными HTML файлами. Вы можете использовать это только в том случае, если хотите вставить CSS в HTML, который вы загрузили в приложение.
ОБНОВЛЕНИЕ: WKWebView/Swift 3.x
Когда вы работаете с инъекцией WKWebView
элемент <link>
не работает из-за WKWebView
безопасности WKWebView
.
Вы можете добавить css в строку. Либо создайте строку CSS в коде //1
либо поместите ее в локальный файл //2
. Просто имейте в виду, что с WKWebView вам нужно сделать инъекцию в WKNavigationDelegate
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)
}
Ответ 2
Поскольку UIWebView
устарела в iOS 12, я отвечу только за WKWebView
.
Я реализовал загрузку CSS, как это было описано в принятом ответе. Проблема заключалась в том, что иногда переход от HTML без CSS к HTML с CSS был видимым.
Я думаю, что лучший подход - использовать 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
}()
Подробнее об этом подходе можно прочитать в этом блоге.
Ответ 3
Вместо применения css с тегом style лучше применять его с тегом link:
func insertContentsOfCSSFile2(into webView: WKWebView) {
guard let path = Bundle.main.path(forResource: "resource", ofType: "css") else { return }
let csFile = "var head = document.getElementsByTagName('head')[0];var link = document.createElement('link'); link.rel = 'stylesheet';link.type = 'text/css';link.href = '\(path)';link.media = 'all';head.appendChild(link);"
webView.evaluateJavaScript(csFile) {(result, error) in
if let error = error {
print(error)
}
}
}
Я проверил это. это работает нормально.
Ответ 4
Для получения более подробной информации см. @Joern. Я добавляю этот ответ, потому что я столкнулся с странным случаем. Мой конкретный пример использования должен был добавить стиль в div
с помощью class="dialog"
. По какой-то причине стиль с использованием .dialog
и div
не работал, хотя работали другие типы стилей. В конце я использовал следующее, чтобы установить ширину dialog
let width = Int(webView.bounds.width)
let script = "document.getElementsByClassName(\"dialog\")[0].style.width = \"\(width)px\""
webView.evaluateJavaScript(script)
Ответ 5
Вы должны добавить этот заголовок перед стилем Apple в HTML
let fontName = UIFont.systemFont(ofSize: 17.0).fontName
let htmlContent = """
<header>
<meta name='viewport' content='width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no'>
</header>
<style type='text/css'>
img{max-height: 100%; min-height: 100%; height:auto; max-width: 100%; width:auto;margin-bottom:5px;}
p{text-align:left|right|center; line-height: 180%; font-family: '\(fontName)'; font-size: 17px;}
iframe{width:100%; height:250px;}
</style> \(html)
"""
webView.loadHTMLString(htmlContent, baseURL: Bundle.main.bundleURL)