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スタイルシートを取得するのを手伝ってください。
次のようにできます:
_- (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:新しい_<style>
_ HTML DOM要素を作成し、それにCSS宣言を挿入するjavascript文字列を定義します。実際には、次のステップで挿入が行われますが、現在は_%@
_プレースホルダーのみがあります。行が長くなりすぎるのを防ぐためにこれを行いましたが、ステップ2と3は一緒に実行できます。
// 3:2つの文字列を組み合わせます
// 4:UIWebViewでJavaScriptを実行します
これが機能するには、HTMLに_<head></head>
_要素が必要です。
編集:
ローカルのCSSファイル(この場合は「styles.css」という名前)からCSS文字列をロードすることもできます。ステップ// 1を次のように置き換えます。
_NSString *path = [[NSBundle mainBundle] pathForResource:@"styles" ofType:@"css"];
NSString *cssString = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:nil];
_
別のオプションとして、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];
}
_
このソリューションは、大きなCSSファイルに最適です。残念ながら、リモートHTMLファイルでは機能しません。これは、アプリにダウンロードしたHTMLにCSSを挿入する場合にのみ使用できます。
更新:WKWebView/Swift 3.x
WKWebView
のセキュリティ設定のため、WKWebView
を使用して_<link>
_要素を挿入しても機能しません。
それでも、CSSを文字列として挿入できます。コード_//1
_にCSS文字列を作成するか、ローカルファイル_//2
_に配置します。 WKWebViewでは、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)
}
_
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
}()
このアプローチの詳細については、こちらをご覧ください ブログ投稿 。
スタイルタグでCSSを適用する代わりに、リンクタグでCSSを適用することをお勧めします:
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)
}
}
}
私はそれをテストしました。それはうまく機能しています。
詳細については、@ joernの承認済みの回答を参照してください。奇妙なEdgeのケースに遭遇したので、この答えを追加しています。 class="dialog"
を使用してdiv
にスタイルを追加するために必要な私の特定の使用例。何らかの理由で、.dialog
およびdiv
を使用したスタイリングは機能しませんでしたが、他のタイプのスタイリングは機能していました。最後に、以下を使用してdialog
の幅を設定しました
let width = Int(webView.bounds.width)
let script = "document.getElementsByClassName(\"dialog\")[0].style.width = \"\(width)px\""
webView.evaluateJavaScript(script)