緣起
我們通常都會在webViwe控件的下面繪制很多其他的內容,不但webView中的內容需要全部展現,并且webView底部的內容也應當完美銜接,例如下面的效果:

基本方法
在網頁加載完成后,通過JS方法獲取內容高度
在[webView:didFinishNavigation:]方法內,通過JS來獲取頁面的高度:
- (void)webView:(WKWebView *)webView didFinishNavigation:(null_unspecified WKNavigation *)navigation {
[webView evaluateJavaScript:@"document.body.scrollHeight" completionHandler:^(id _Nullable result,NSError *_Nullable error) {
//獲取頁面高度
CGFloat scrollHeight = [result doubleValue];
NSLog(@"scrollHeight 即為所求:%f",scrollHeight);
}];
}
但是,
經常會遇見scrollHeight高度計算不準確的情況,此時html內容底部會有很大一塊空白,我們經常會在webView的底部再堆一些其他的功能,此時界面看上去簡直丑爆了,例如:

因此,
因此有很多方法告訴我們,需要在html中設置一些style,例如給img設置寬度、設置設備寬度等,例如像下面這樣:
NSInteger limitWidth = 375-30;
NSInteger fontSize = 15;
NSInteger lineHeight = 20;
NSMutableString *strReturn = [NSMutableString stringWithCapacity:1];
[strReturn appendString:@"<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">"];
[strReturn appendString:@"<html><head>"];
[strReturn appendString:@"<meta content=\"width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0\" name=\"viewport\"><meta http-equiv=\'Content-Type\' content=\'text/html; charset=utf-8\'/><meta content=\'width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0;\' name=\'viewport\' /><meta name=\'apple-mobile-web-app-capable\' content=\'yes\'><meta name=\'apple-mobile-web-app-status-bar-style\' content=\'black\'>"];
[strReturn appendFormat:@"<style type=\"text/css\">\
html,body {} \
#content { overflow:hidden;}\
h1 {font-family:Arial;font-size:14px;font-weight:normal;color:#666666;text-align: left;} \
p{text-align:justify;text-justify:Distribute-all-lines;line-height:%ldpx; font-size: %ldpx;color:#373737;font-weight:normal;word-wrap: break-word; white-space: pre-line; } \
h2{font-size: 18px;text-align: left;font-weight:bold;} </style>",(long)lineHeight,(long)fontSize];
[strReturn appendString:@"</head><body>"];
或者,
或者還有通過KVO來監(jiān)聽webView的contentSize變化的方法,例如下面這樣:
- (void)addObserver {
[self.webViewCurrent addObserver:self forKeyPath:@"contenSize" options:NSKeyValueObservingOptionNew context:nil];
}
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context {
if([keyPath isEqualToString:@"contentSize"]) {
CGSize fittingSize = [self.webViewCurrent sizeThatFits:CGSizeZero];
NSLog(@"webView:%@",NSStringFromCGSize(fittingSize));
[self layoutUIWithWebViewHeight:fittingSize.height];
}
}
再或者,
再或者,對webView進行一些設置,例如下面這樣:
- (WKWebView *)webViewCurrent {
if(!_webViewCurrent){
//以下代碼適配大小
NSString *jScript = @"var meta = document.createElement('meta'); meta.setAttribute('name', 'viewport'); meta.setAttribute('content', 'width=device-width'); document.getElementsByTagName('head')[0].appendChild(meta);";
WKUserScript *wkUScript = [[WKUserScript alloc] initWithSource:jScript injectionTime:WKUserScriptInjectionTimeAtDocumentEnd forMainFrameOnly:YES];
WKUserContentController *wkUController = [[WKUserContentController alloc] init];
[wkUController addUserScript:wkUScript];
WKWebViewConfiguration *wkWebConfig = [[WKWebViewConfiguration alloc] init];
wkWebConfig.userContentController = wkUController;
_webViewCurrent = [[WKWebView alloc] initWithFrame:CGRectMake(0, 0, WIDTH_SCREEN, 0) configuration:wkWebConfig];
_webViewCurrent.backgroundColor = [UIColor whiteColor];
_webViewCurrent.navigationDelegate = self;
_webViewCurrent.scrollView.bounces = NO;
_webViewCurrent.scrollView.alwaysBounceVertical = NO;
_webViewCurrent.scrollView.scrollEnabled = NO;
_webViewCurrent.alpha = 0;
[self.myScrollView addSubview:_webViewCurrent];
}
return _webViewCurrent;
}
但是,
但是,這些方法都有一個問題,就是當內容很少的時候,webView會給自己一個倔強的高度,例如:724,這個缺省高度要比真實的內容高出來很多,因此底部還是會有空白;
試試神奇法
只需在webView的loadHTMLString:baseURL:方法執(zhí)行之前或之后將webView的高度強行設置為0,此時webView貌似就放棄了那個倔強的缺省高度,而是按照真實的內容來返回了,就像下面這樣:
CGRect frame = self.webViewCurrent.frame;
frame.size.height = 0;
self.webViewCurrent.frame = frame;
[self.webViewCurrent loadHTMLString:htmlString baseURL:nil];
此時,似乎完全不再需要進行 css/style/kvo/配置webView 等復雜操作,一切都可以完美進行了;
Review 回顧一下神奇方法
第一步:
只需在webView的loadHTMLString:baseURL:方法執(zhí)行之前或之后將webView的高度強行設置為0,此時webView貌似就放棄了那個倔強的缺省高度,而是按照真實的內容來返回了,就像下面這樣:
CGRect frame = self.webViewCurrent.frame;
frame.size.height = 0;
self.webViewCurrent.frame = frame;
[self.webViewCurrent loadHTMLString:htmlString baseURL:nil];
第二步:
在網頁加載完成后,通過JS方法獲取內容高度
在[webView:didFinishNavigation:]方法內,通過JS來獲取頁面元素的高度:
- (void)webView:(WKWebView *)webView didFinishNavigation:(null_unspecified WKNavigation *)navigation {
[webView evaluateJavaScript:@"document.body.scrollHeight" completionHandler:^(id _Nullable result,NSError *_Nullable error) {
//獲取頁面高度
CGFloat scrollHeight = [result doubleValue];
NSLog(@"scrollHeight 即為所求:%f",scrollHeight);
}];
}
重要聲明:
本方法僅進行過簡單測試,
在iOS12+iPhoneXS模擬器、iOS9+iPhone5s模擬器兩種模式下,
使用純文字或圖文混排的Html,
貌似都可以正常運行,以后發(fā)現錯誤了再來勘誤吧。
如果這個方法把大家?guī)У搅藴侠?,還請多多見諒