上班了,寫代碼,寫代碼。不適應,藍瘦香菇
今天遇到一個問題。就是原先的彈框裏面是一個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
}()
打完收工,趕緊提測。