一個自動適應內容高度的WebView For iOS

上班了,寫代碼,寫代碼。不適應,藍瘦香菇

今天遇到一個問題。就是原先的彈框裏面是一個UIWebView,產品說隨着內容的高度變化而變化,固定高度不滿足需求。

好久沒有做UI了,還以爲UIWebView.scrollView.contentSize.height在webViewDidFinishLoad中可以獲取到。但是我錯了。Sometimes naive!!!

由於控件是UIWebView,內容是本地資源文件,因此

- (void)loadHTMLString:(NSString *)string baseURL:(nullable NSURL *)baseURL;

self.webView.scrollView.scrollEnabled = NO;
self.webView.scrollView.bounces = NO;
self.webView.delegate = self;

設置好後

- (void)webViewDidFinishLoad:(UIWebView *)webView

{

    NSString *state = [webView stringByEvaluatingJavaScriptFromString:@"document.readyState"];

    if ([state isEqualToString:@"complete"])

    {

        NSString *html = [webView stringByEvaluatingJavaScriptFromString: @"document.body.innerHTML"];

        float width = [[webView stringByEvaluatingJavaScriptFromString:@"document.documentElement.scrollWidth"] floatValue];

        float height = [[webView stringByEvaluatingJavaScriptFromString:@"document.documentElement.scrollHeight"] floatValue];

      // TODO

       ...

    }

}

這裏面有一個比較重要的點:

1. html文件中的head標籤需要一個metadata標籤
<meta name="viewport" content="width=device-width,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no"/>
2. baseURL參數需要使用main bundle的NSURL,因爲需要加載字體,CSS等去計算真實的高度。

 

如果你是WKWebView的使用者

這裏面涉及到加載CSS文件,比UIWebView要略微麻煩一點

func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
    guard
        let path = Bundle.main.path(forResource: "style", ofType: "css"),
        let cssString = try? String(contentsOfFile: path).components(separatedBy: .newlines).joined()
    else {
        return
    }

    let jsString = "var style = document.createElement('style'); style.innerHTML = '\(cssString)'; document.head.appendChild(style);"
    webView.evaluateJavaScript(jsString)
}

 

還有一個更順滑的方法,CSS在HTML加載之後纔會去加載,渲染比較平滑

lazy var webView: WKWebView = {
    guard
      let path = Bundle.main.path(forResource: "style", ofType: "css"),
      let cssString = try? String(contentsOfFile: path).components(separatedBy: .newlines).joined()
    else {
      return WKWebView()
    }

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

打完收工,趕緊提測。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章