起因
公司提出要更改部分界面。其中一个界面是嵌入了一个webView的。要求整个页面都可以上下滚动,且一个UITextView放在UIWebView下面。
难点
- UIWebView 的滚动要和 整个页面的滚动保持一致。只能让整个UIWebView自适应实际内容高度。
- 加载的网页的高度是可以动态改变的。也就是说网页加载完成后,网页高度可变。
分析
- 整体滚动无疑要用UIScrollView。网页加载完成后,网页的高度变化时,要更改UIWebView的高度,进而影响到UITextView的origin.y和UIScrollView的contentSize。嗯,用autolayout很好解决。
- 网页的完整高度=document.body.offsetHeight。用stringByEvaluatingJavaScriptFromString:在webViewDidFinishLoad:中获取。
- 网页加载完成后的高度改变,用JavaScriptCore监听对应的事件。
结果
- UIWebView自适应实际内容高度 :
dispatch_async(dispatch_get_main_queue(), ^{
CGFloat webViewHeight = [[webView stringByEvaluatingJavaScriptFromString:@"document.body.offsetHeight"] floatValue];
});
这里的webViewHeight 实际使用时出现了无法完全展示网页的情况,最终在这个值的基础上加上100,解决!
- 网页加载完成后,网页高度可变 :
JSContext *context=[webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
context[@"htmlHeightChangeEvent"] = ^{
//上述获取高度的方法
dispatch_async(dispatch_get_main_queue(), ^{
CGFloat webViewHeight = [[webView stringByEvaluatingJavaScriptFromString:@"document.body.offsetHeight"] floatValue];
});
}];
不同步到主线程,会在网页加载完成后,改变网页高度时,报‘警告’,大意是说有可能出现诡异的错误。