標籤:對比 javascrip 導致 top enable 顯示 dexp 處理 spec
前言:是這樣的,剛寫完上一篇文章還沒緩過神來,上一篇文章我還提到了,想和大家聊聊原生+H5如何無縫串連的故事.結果我朋友就給我發了兩篇他的作品.他的做法也都有獨到之處.好的文章都是這樣,讓你每次看都能有新的收穫,我們也都致力於寫一些能幫別人解決問題的文章,下面我用另一種方式來完美實現這個問題.畢竟之前大家都是根據UIWebView寫的,我來說說換成WK之後的區別,主題思路也不同哦~
插兩個連結,是我朋友的大家也可以做個對比
iOS 【終極方案】精準擷取webView內容高度,自適應高度
iOS 【奇巧淫技】擷取webView內容高度
iOS WKWebView 圖片點擊放大並左右滑動,類似/網易文章功能
首先先說應用情境吧,這樣大家可能更能接受一點
例1:一個頁面 分為上下兩個部分,上部分為文章,商品圖文介紹等(H5)一個web,下半部分是原生的列表(tableView)
那麼怎麼把H5和原生結合在一起呢,最簡單的思想就是把H5做成表頭,對吧.那麼擷取Web部分的真實高度就是最大的痛點公關.
例2:上面是一個原生介紹,下面分為3部分,其中一部分是H5頁面的詳情介紹,一部分是評論列表,一部分是相關推薦等等,這樣,最合理的結構就是:上面作為一個Tabview的表頭,下面共用同一個tabview,將H5的web嵌入成某一種tableviewCell當中.那麼痛點就是怎麼擷取Web這個cell的高度返回.
我就拿第二種來舉例子吧.畢竟第二種更複雜一些,而且例1 很多工程都實現了,我朋友的文章也能實現這個功能,第二種例子,我用WKWebView給大家提供一個新的思路.
嗶嗶叨叨了這麼多,下面開始說正題吧.
首先跟大家說一下,簡單的擷取contentSize 什麼的(網上一搜隨處可見的那幾個方法)我就不吐槽了,他們的應用情境太局限了,稍微在進行富文本編輯的時候 插入的圖片 尺寸 或者某些動圖之類的 都會導致你擷取的高度不準,然後介面UI噁心到不行.
那麼思路依舊是跟我上一篇文章一樣 利用JS注入來解決
首先從載入的時候開始
- (instancetype)initWithStyle:(www.8861788.cn/ UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if(self){
self.contentView.backgroundColor = NineColorOne;
[self creatSubviews];
}
return self;
}
- (void)creatSubviews
{
WKWebViewConfiguration *confifg = [[WKWebViewConfiguration alloc] init];
confifg.selectionGranularity = WKSelectionGranularityCharacter;
_webView = [[WKWebView alloc] initWithFrame:CGRectMake(14, 0, CurrentScreenWidth - 28, 1) configuration:confifg];
self.contentView.backgroundColor = NineColorOne;
// _webView.scalesPageToFit = NO;
_webView.scrollView.scrollEnabled=NO;
_webView.userInteractionEnabled = NO;
_webView.opaque = NO;
_webView.scrollView.bounces=NO;
_webView.backgroundColor=NineColorOne;
_webView.scrollView.decelerationRate=UIScrollViewDecelerationRateNormal;
[self.contentView addSubview:_webView];
}
我剛才說了,把web放在一個cell裡,那麼它的代理就要在VC裡面去簽.
大家注意到,_webView.scalesPageToFit = NO;這句話我屏蔽掉了,因為WKWebView是沒有這個屬性的 它和UIWebView不同,然而 如果不設定NO, WKWebView的預設效果和UIWebView.scalesPageToFit = YES是一樣的,這時候,你需要這段代碼:
<meta content=\"width=device-width, initial-scale=1.0,
www.chonylpt.com maximum-scale=3.0, user-scalable=0;\" name=\"viewport\" />
1
這段代碼 注入在載入的時候
例如:
- (void)setDetail:(NSString *)detail
{
if(!_detail){
_detail = detail;
if (_detail.length >0) {
[_webView loadHTMLString:[NSString stringWithFormat:@"<meta content=\"width=device-width, initial-scale=1.0, maximum-scale=3.0, user-scalable=0;\" name=\"viewport\" />%@<div id=\"testDiv\" style = \"height:100px; width:100px\"></div>",_detail] baseURL:[NSURL fileURLWithPath: [[NSBundle mainBundle] bundlePath]]];
注意2點:
1.因為整體邏輯是 Web放在cell裡,載入完成後重新整理tabview,那麼重新整理的時候 走代理方法cellforrow,則cell會重新賦值,產生死鏈.所以在賦值時候要做基本處理
2.我在注入scalesPageToFit代碼的同時,似乎還加了一個div?對的,你沒有看錯.下面我就說一說,這個div是幹什麼用的
我們將目光切回到VC
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
_webview = cell.webView;
cell.webView.navigationDelegate = self;
cell.webView.UIDelegate = self;
cell.selectionStyle = 0;
這是代理方法裡面cell的部分代碼.可以看到 代理我們都簽在了VC裡
緊接著看載入完成方法
- (void)webView:(WKWebView *)webView didFinishNavigation:(www.t1yl9.cn/ null_unspecified WKNavigation *)navigation
{
[webView evaluateJavaScript:@"document.getElementById(www.120xh.cn/\"testDiv\").offsetTop"completionHandler:^(id _Nullable result,NSError * _Nullable error) {
//擷取頁面高度,並重設webview的frame
CGFloat lastHeight = [result doubleValue];
webView.frame = CGRectMake(14, 0, CurrentScreenWidth - 28, lastHeight);
webHeight = lastHeight;
[self.tableView beginUpdates];
[self.tableView endUpdates];
注意看一下這裡,首先WK的JS注入方法有變化,其次就是你發現我取web的高度利用了我剛才在載入HTML時注入的div塊
這樣,不管你的網頁是什麼樣的,在尾部加一個div它的位置永遠是你需要的高度.(一定要注意這段代碼不加的話 擷取的高度同樣不準哦)
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
if(_type == 0){
return webHeight;
}// 當前tableview是載入web狀態時 cell返回高度
那麼這個時候 你還會發現,滾動tableView時,web顯示內容沒有變化!!!
對,這就是WKWebView的另一個區別,由於WKWebView採用的lazy載入模式,所在的scrollView的滾動被禁用,導致被嵌套的WKCompositingView不進行資料載入。
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
// 判斷webView所在的cell是否可見,如果可見就layout
NSArray *cells = self.tableView.visibleCells;
for (UITableViewCell *cell in cells) www.wmyl1.cn {
if ([cell isKindOfClass:[UITableViewCell class]]) {
UITableViewCell *www.ysyl157.com webCell = (UITableViewCell *)cell;
[webCell.webView setNeedsLayout];
你需要加上這個代碼.
嗯這時候,H5和原生就完美的無縫串連了.
這些東西也並非我一個人獨立想出來的,在這裡也對我的好朋友–徐陽 表示由衷的感謝,是他給我提供了很多思路.對,就是上面我推薦文章的那個人.
還不知道下一篇想寫什麼,最近忽然又對寫部落格起了興趣.
頂
0
踩
iOS 【終極方案】精準擷取webView內容高度,自適應高度