上班了,写代码,写代码。不适应,蓝瘦香菇
今天遇到一个问题。就是原先的弹框里面是一个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
}()
打完收工,赶紧提测。