日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

wkwebview 下移20像素_UITableView嵌套WKWebView的那些坑

發(fā)布時(shí)間:2023/12/15 编程问答 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 wkwebview 下移20像素_UITableView嵌套WKWebView的那些坑 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

原標(biāo)題:UITableView嵌套WKWebView的那些坑

最近項(xiàng)目中遇到了一個(gè)需求,TableView中需要嵌套Web頁(yè)面,我的解決辦法是在系統(tǒng)的UITableViewCell中添加WKWebView。開(kāi)發(fā)的過(guò)程中,遇到了些坑,寫(xiě)出來(lái)分享一下。

1.首先說(shuō)一下WKWebView的代理方法中,頁(yè)面加載完成后會(huì)走的代理方法,與UIWebView的頁(yè)面加載完成代理方法一樣。

- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation

- (void)webViewDidFinishLoad:(UIWebView *)webView;

這兩個(gè)方法都是在web頁(yè)面加載完成后才會(huì)走的代理方法。什么才算是加載完成呢?web頁(yè)面中的所有元素都加載成功,包括圖片、音頻和視頻等資源,都加載成功了,才算加載完成。如果通過(guò)這兩個(gè)代理方法來(lái)計(jì)算cell的高度,你的整個(gè)tableview頁(yè)面就會(huì)加載得很慢,至少要等web頁(yè)面加載完成后才能計(jì)算高度重鋪tableview。

2.WKWebView加載完成展示頁(yè)面的時(shí)候,會(huì)讓整個(gè)web頁(yè)面自動(dòng)適應(yīng)屏幕的寬度。這樣展示出來(lái)的效果就會(huì)很緊湊,頁(yè)面內(nèi)容會(huì)很小。

為了讓web頁(yè)面中的元素都適應(yīng)屏幕的寬度顯示,需要對(duì)WKWebView進(jìn)行一下設(shè)置,原理是加載js代碼,然后通過(guò)js來(lái)設(shè)置webview中的元素大小:

WKWebViewConfiguration *webConfig = [[WKWebViewConfiguration alloc] init];

WKUserContentController *wkController = [[WKUserContentController alloc] init];

webConfig.userContentController = wkController;

// 自適應(yīng)屏幕寬度js

NSString *jsStr = @"var meta = document.('meta'); meta.setAttribute('name', 'viewport'); meta.setAttribute('content', 'width=device-width'); document.getElementsByTagName('head')[0].(meta);";

WKUser *wk = [[WKUser alloc] initWithSource:jsStr injectionTime:WKUserInjectionTimeAtDocumentEnd forMainFrameOnly:YES];

// 添加js調(diào)用

[wkUController addUser:wk];

WKWebView *webView = [[WKWebView alloc] initWithFrame:self.view.frame configuration:webConfig];

如果加載的是HTML代碼,圖片的自適應(yīng)可以通過(guò)下面一段CSS代碼來(lái)設(shè)置:

NSString *html = @"HTML代碼";

NSString *cssStr = @"";

NSString *htmlStr = [NSString stringWithFormat:@"

webview%@%@", cssStr, html];

[webView loadHTMLString:htmlStr baseURL:nil];

3.接下來(lái)說(shuō)說(shuō)重頭戲,UITableViewCell嵌套WKWebView。

(1)cell的高度自適應(yīng)(筆者用的是系統(tǒng)的cell,UITableViewCell)

cell的高度當(dāng)然是根據(jù)webview的高度來(lái)設(shè)置的,所以首先要算出webview頁(yè)面的高度。開(kāi)篇就已經(jīng)說(shuō)過(guò),webview加載完成的代理方法是web頁(yè)面中的所有元素都加載成功,包括圖片、音頻和視頻等資源,都加載成功了,才算加載完成。如果頁(yè)面中的元素過(guò)多,網(wǎng)絡(luò)圖片過(guò)大,視頻過(guò)大等,就會(huì)導(dǎo)致web頁(yè)面加載卡頓。本身WKWebView這些資源是異步加載的,但是計(jì)算cell高度的時(shí)候是在這些資源都加載完成后才計(jì)算高度,WKWebView也就失去的異步加載的意義,所以整個(gè)tableview都會(huì)加載得很慢。

明白了這個(gè)道理,我個(gè)人推薦使用KVO來(lái)代替webview的代理方法。

// 對(duì)webView中的scrollView設(shè)置KVO

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

// KVO具體實(shí)現(xiàn)

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context

{

if ([keyPath isEqualToString:@"contentSize"]) {

// 這里有兩種方法獲得webview高度,第一種就是通過(guò)JS代碼來(lái)計(jì)算出高度,如下

// document.documentElement.scrollHeight

// document.body.offsetHeight

/*

[_webView evaluateJava:@"document.body.offsetHeight" completionHandler:^(id _Nullable result, NSError * _Nullable error) {

// 加20像素是為了預(yù)留出邊緣,這里可以隨意

CGFloat height = [result doubleValue] + 20;

// 設(shè)置一個(gè)高度屬性,賦值后便于設(shè)置cell的高度

_webHeight = height;

// 設(shè)置cell上子視圖的frame,主要是高度

_webView.frame = CGRectMake(0, 0, kScreenWidth, height);

_scrollView.frame = CGRectMake(0, 0, kScreenWidth, height);

_scrollView.contentSize =CGSizeMake(kScreenWidth, height);

// 獲取了高度之后,要更新webview所在的cell,其他的cell就不用更新了,這樣能更節(jié)省資源

[self.tableView reloadRowsAtIndexPaths:[NSArray arrayWithObjects:[NSIndexPath indexPathForRow:1 inSection:0], nil] withRowAnimation:UITableViewRowAnimationNone];

}];

*/

// 第二種方法就是直接使用監(jiān)聽(tīng)的contentSize.height(這里要感謝[markss](http://www.jianshu.com/u/cc0bd919cb50)簡(jiǎn)友的評(píng)論提醒),但是與第一種方法不同的就是不能再加多余的高度了,那樣會(huì)循環(huán)出發(fā)KVO,不斷的增加高度直到crash。

UIScrollView *scrollView = (UIScrollView *)object;

CGFloat height = scrollView.contentSize.height;

_webHeight = height;

_webView.frame = CGRectMake(0, 0, kScreenWidth, height);

_scrollView.frame = CGRectMake(0, 0, kScreenWidth, height);

_scrollView.contentSize =CGSizeMake(kScreenWidth, height);

[self.tableView reloadRowsAtIndexPaths:[NSArray arrayWithObjects:[NSIndexPath indexPathForRow:1 inSection:0], nil] withRowAnimation:UITableViewRowAnimationNone];

}

}

// 別忘注銷(xiāo)kvo

- (void)dealloc

{

[_webView.scrollView removeObserver:self forKeyPath:@"contentSize"];

}

這樣設(shè)置后的webView直接addSubview到webCell.contentView上,頁(yè)面是加載出來(lái)了,但是webView的高度并不能改變。

(2)然后筆者百度了一下,找到了一個(gè)方法。就是先將webView addSubview到一個(gè)scrollView上

[_scrollView addSubview:_webView];

然后再將這個(gè)scrollView addSubview到webCell.contentView上

[webCell.contentView addSubview:_scrollView];

這樣webview的高度就可以改變了。但是這是什么原理,筆者還沒(méi)搞清楚,希望懂的大神能給予熱情而細(xì)心的指導(dǎo)。

(3)在刷新tableview刷新cell的時(shí)候,會(huì)重新走一遍所有的tableview代理方法,所以筆者建議盡量?jī)?yōu)化- (UITableViewCell )tableView:(UITableView )tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath中的代碼,防止多次加載webview

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath

{

switch (indexPath.row) {

case 0:

{

ArticleHeaderTableViewCell *articleHeaderCell = [tableView dequeueReusableCellWithIdentifier:_articleHeaderIdentifier forIndexPath:indexPath];

return articleHeaderCell;

}

break;

case 1:

{

// 嵌套webivew的cell

UITableViewCell *webCell = [tableView dequeueReusableCellWithIdentifier:_articleWebIdentifier forIndexPath:indexPath];

[webCell.contentView addSubview:_scrollView];

return webCell;

}

break;

case 2:

{

ArticleCommentTableViewCell *articleCommentCell = [tableView dequeueReusableCellWithIdentifier:_articleCommentIdentifier forIndexPath:indexPath];

return articleCommentCell;

}

break;

default:

{

CommentsTableViewCell *commentsCell = [tableView dequeueReusableCellWithIdentifier:_commentsIdentifier forIndexPath:indexPath];

return commentsCell;

}

break;

}

}

總結(jié):

1.在cell上嵌套webview之前,一定要在中間多加一層scrollview。

2.在計(jì)算cell高度的時(shí)候,不建議直接使用系統(tǒng)webview的代理方法,建議使用kvo。

3.進(jìn)行減少- (UITableViewCell )tableView:(UITableView )tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath方法中對(duì)webview的操作,這樣能減少webview的重復(fù)加載,提高性能和速度。

PS:每個(gè)人都有自己的想法,每個(gè)人的優(yōu)化方式不同,筆者也是在摸索中嘗試著,如果有說(shuō)得不對(duì)不準(zhǔn)確的地方,還請(qǐng)各位指正出來(lái),大家共同探討,互相學(xué)習(xí)。

代碼下載地址:https://github.com/VonKeYuan/WKWebViewTest

作者:天蝎座的Von動(dòng)必曬

鏈接:http://www.jianshu.com/p/44cfcf0fd538

程序員大咖整理發(fā)布,轉(zhuǎn)載請(qǐng)聯(lián)系作者獲得授權(quán)。返回搜狐,查看更多

責(zé)任編輯:

總結(jié)

以上是生活随笔為你收集整理的wkwebview 下移20像素_UITableView嵌套WKWebView的那些坑的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。