UITableView與WKWebView的巢狀與適配

LeeJTom發表於2018-01-03

更新

2018年05月22日

陸續有使用者反映有一些文章無法檢視。除錯(XCode9.3 (9E145))發現:在瀏覽多圖文章時報以下問題:

  1. 報記憶體不足問題

下面是修改內容:

  1. 刪除以前的方法,WKWebView直接新增到cell的contentView裡面
//	[self.contentScrollView addSubview:self.webView];
//	[self.contentView addSubview:self.contentScrollView];
	[self.contentView addSubview:self.webView];
複製程式碼
  1. 更新高度方法修改,使用此方法可以只修改cell高度
    [self beginUpdates];
    [self endUpdates];
複製程式碼

更好方案&參考資料

UIWebView與UITableView的巢狀方案

UIWebView與tableView巢狀的記憶體問題及解決方案

UITableView的 beginUpdates 和 endUpdates

背景

因專案需要,需要在UITableView中加入HTML與評論功能。下面作為此次爬坑的一次記錄。):

總結
  • UITableView與WKWebView的結合與適配,關鍵在於要先將WKWebView裝進UIScrollview後再放進UITableViewCell裡面去。

  • 獲取WKWebView的正確高度,放到網頁載入完成的代理方法裡面,使用js獲取。

初始化
#import <WebKit/WebKit.h>
#define kScreenW [UIScreen mainScreen].bounds.size.width
#define kScreenH [UIScreen mainScreen].bounds.size.height
static CGFloat MARGIN = 24;

@property(strong, nonatomic)UIScrollView *contentScrollView;
@property(strong, nonatomic)WKWebView *wkWebView;

-(WKWebView *)wkWebView{
	if (!_wkWebView) {
		WKWebViewConfiguration *config = [[WKWebViewConfiguration alloc]init];
		config.allowsInlineMediaPlayback = YES;//使用H5播放視訊
		_wkWebView = [[WKWebView alloc]initWithFrame:CGRectMake(0, 0, kScreenW, 0) configuration:config];
		_wkWebView.navigationDelegate=self;
		_wkWebView.scrollView.scrollEnabled=NO;//禁止滾動,防止與UITableView衝突
	}
	return _wkWebView;
}

-(UIScrollView *)contentScrollView{
	if (!_contentScrollView) {
		_contentScrollView = [[UIScrollView alloc]init];
		_contentScrollView.contentSize=CGSizeMake(kScreenW, kScreenH);
		_contentScrollView.scrollEnabled=NO;//禁止滾動,防止與UITableView衝突
	}
	return _contentScrollView;
}

/**
 初始化WKWebView
 */
-(void)initWebView{
	[self.view addSubview:self.wkWebView];//需要先將WKWebView加入到view中
	NSString *urlString =@"測試地址";
	NSURLRequest *urlRequest = [[NSURLRequest alloc]initWithURL:[NSURL URLWithString:urlString] ;
	[self.wkWebView loadRequest:urlRequest];
}

複製程式碼
WKWebView放進UITableViewCell的正確開啟方式
解決:WKWebView無法顯示完全問題

先將WKWebView放進UIScrollview,再把Scrollview放進Cell。

/**
 WKWebView cell
 @return cell
 */
-(UITableViewCell *)wkWebViewCell{
	
	UITableViewCell *cell = [[UITableViewCell alloc]init];
	cell.selectionStyle=UITableViewCellSelectionStyleNone;
	//解決WKWebView無法顯示完全問題。先新增到scrollview
	self.contentScrollView.frame = self.wkWebView.bounds;
	[self.contentScrollView addSubview:self.wkWebView];
	
	[cell.contentView addSubview:self.contentScrollView];
	return cell;
}
複製程式碼
如何正確獲取WKWebView高度
實現WKNavigationDelegate代理方法以獲取HTML高度
-(void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation{
	//獲取網頁正文全文高,重新整理cell
	[webView evaluateJavaScript:@"document.body.scrollHeight" completionHandler:^(id _Nullable result, NSError * _Nullable error) {
		self.wkWebView.frame=CGRectMake(0, MARGIN, self.view.width, [result doubleValue]+ MARGIN);//將WKWebView的高度設定為內容高度
		//重新整理制定位置Cell
		[self refreshWebViewCell];
	}];
}
複製程式碼
重新整理Cell高度
-(void)refreshWebViewCell{
	[self.myTableView reloadRowsAtIndexPaths:@[[NSIndexPath indexPathForRow:1 inSection:0]] withRowAnimation:UITableViewRowAnimationNone];//重新整理制定位置Cell
}
複製程式碼

cell高度返回WKWebView的高度即可。

-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
return self.wkWebView.heigth;
}
複製程式碼
記錄一個情況

就是WKWebView初始化的時候,高度隨便設定為一個非零的數字時,在js獲取高度時會不準。

HTML附加內容

網頁可見區域寬: document.body.clientWidth 網頁可見區域高: document.body.clientHeight 網頁可見區域寬: document.body.offsetWidth (包括邊線的寬) 網頁可見區域高: document.body.offsetHeight (包括邊線的高) 網頁正文全文寬: document.body.scrollWidth 網頁正文全文高: document.body.scrollHeight 網頁被捲去的高: document.body.scrollTop 網頁被捲去的左: document.body.scrollLeft 網頁正文部分上: window.screenTop 網頁正文部分左: window.screenLeft 螢幕解析度的高: window.screen.height 螢幕解析度的寬: window.screen.width 螢幕可用工作區高度: window.screen.availHeight 螢幕可用工作區寬度: window.screen.availWidth

相關文章