ios - app - Inserte CSS en HTML cargado en UIWebView/WKWebView
wkwebview ios (4)
Como
UIWebView
está en desuso en iOS 12, solo responderé por
WKWebView
.
Implementé la carga CSS como se describió en la respuesta aceptada.
El problema era que a veces la transición de HTML sin CSS aplicado a HTML con CSS era visible.
Creo que un mejor enfoque es usar el
WKUserScript
para inyectar el CSS de esta manera:
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
}()
Puede leer más sobre este enfoque en esta publicación de blog .
Puedo obtener con éxito contenido HTML y mostrarlo en mi UIWebView.
Pero desea personalizar el contenido agregando un archivo CSS externo. Solo puedo cambiar el tamaño del texto y la fuente. Intenté todas las soluciones posibles para hacer cambios, pero no funciona, no muestra cambios.
Abajo está mi código
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];
}
Ayúdame a obtener la hoja de estilo css en mi vista.
Consulte la respuesta aceptada de @ joern para obtener más detalles completos.
Estoy agregando esta respuesta porque me encontré con un caso marginal extraño.
Mi caso de uso particular necesitaba agregar estilo a un
div
con un
class="dialog"
.
Por alguna razón, el estilo usando
.dialog
y
div
no funcionaba, aunque sí funcionaban otros tipos de estilo.
Al final utilicé lo siguiente para establecer el ancho del
dialog
let width = Int(webView.bounds.width)
let script = "document.getElementsByClassName(/"dialog/")[0].style.width = /"/(width)px/""
webView.evaluateJavaScript(script)
En lugar de aplicar CSS con la etiqueta de estilo, es mejor aplicarlo con la etiqueta de enlace:
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)
}
}
}
Lo he probado Está funcionando bien.
Puedes hacerlo así:
- (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
}
Lo que hace este código:
// 1: definir una cadena que contenga todas las declaraciones CSS
// 2: defina una cadena de JavaScript que cree un nuevo elemento DOM de HTML
<style>
e inserte las declaraciones CSS en él.
En realidad, la inserción se realiza en el siguiente paso, en este momento solo existe el marcador de posición
%@
.
Hice esto para evitar que la línea se alargue demasiado, pero los pasos 2 y 3 se pueden hacer juntos.
// 3: combina las 2 cuerdas
// 4: Ejecuta el javascript en UIWebView
Para que esto funcione, su HTML debe tener un elemento
<head></head>
.
EDITAR:
También puede cargar la cadena css desde un archivo css local (llamado "styles.css" en este caso). Simplemente reemplace el paso // 1 con lo siguiente:
NSString *path = [[NSBundle mainBundle] pathForResource:@"styles" ofType:@"css"];
NSString *cssString = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:nil];
Como otra opción, puede inyectar un elemento
<link>
al
<head>
que carga el archivo 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];
}
Esta solución funciona mejor para archivos CSS grandes. Lamentablemente, no funciona con archivos HTML remotos. Solo puede usar esto cuando desee insertar CSS en HTML que haya descargado en su aplicación.
ACTUALIZACIÓN: WKWebView / Swift 3.x
Cuando trabaja con un
WKWebView
inyección de un elemento
<link>
no funciona debido a la configuración de seguridad de
WKWebView
.
Todavía puede inyectar el CSS como una cadena.
Cree la cadena CSS en su código
//1
o póngala en un archivo local
//2
.
Solo tenga en cuenta que con WKWebView debe hacer la inyección en el
WKNavigationDelegate
webView(_: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)
}