1. 程式人生 > >iOS7,iOS8,iOS9 UIWebView獲取內容高度終極解決方案

iOS7,iOS8,iOS9 UIWebView獲取內容高度終極解決方案

場景

在 App 中載入網頁時,通常情況我們只需要直接初始化一個 WebView,然後去載入對應的 URL 即可,但若是有時候有些個設計是需要將 web 與原生的 UI 搭載在一起,一般情況下,webView 的 內容一頁是肯定不夠的,換句話說,webView 的高度是不定的,那如果原生的 UI是一個 ScrollView,高度也是不定的,那放在一起的話就會有兩個 ScrollView 分別滾動,而這樣的體驗是很差的(嘗試過的都懂)。

這裡的實際場景是: 將 webView 設定為 TableView 的 headerView,tableView 可滾動,WebView 不可滾動。

嘗試

我們想要的結果是將 WebView 設定為不可滾動,與原生的 UI 融合在一起,那這種情況下,我們必須得到 WebView 的內容高度,讓 WebView 的高度與它所需要載入的網頁的內容高度一致,才能讓 WebView 將內容完全顯示。

開始我是在載入完成的回撥中去獲取 webView 的 contentSize的高度

- (void)webViewDidFinishLoad:(UIWebView *)webView{
    webViewHeight=[webView.scrollView contentSize].height;
    CGRect newFrame = webView
.frame; newFrame.size.height = webViewHeight; webView.frame = newFrame; mainTableView.sectionHeaderHeight = webViewHeight; [mainTableView setTableHeaderView:webView]; }

用這樣的方法得到高度很有可能不是web的真實高度,如果web中有很多 圖片未載入完成 的話,獲取的高度將小於真實高度,那在它載入完成後,內容將顯示不全。

解決

最終我是監聽了 webView的 contentSize,每當contentSize的值改變時就去更改webView 的frame。

[activityWebView.scrollView addObserver:self forKeyPath:@"contentSize" options:NSKeyValueObservingOptionNew context:nil];

然後在回撥方法裡改變webView的frame

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
    if ([keyPath isEqualToString:@"contentSize"]) {
        webViewHeight = [[activityWebView stringByEvaluatingJavaScriptFromString:@"document.body.offsetHeight"] floatValue];
        CGRect newFrame       = activityWebView.frame;
        newFrame.size.height  = webViewHeight;
        activityWebView.frame = newFrame;
        [mainTableView setTableHeaderView:activityWebView];
    }
}

在頁面消失時記得 remove 監聽物件,否則會閃退

-(void)viewWillDisappear:(BOOL)antimated{
    [super viewWillDisappear:antimated];
    [activityWebView.scrollView removeObserver:self
forKeyPath:@"contentSize" context:nil];

}轉自:http://my.oschina.net/joanfen/blog/464217?utm_source=tuicool&utm_medium=referral