美文网首页iOS学习
UITableView中加载WKWebView,高度计算问题

UITableView中加载WKWebView,高度计算问题

作者: 元哥830 | 来源:发表于2018-09-17 17:11 被阅读149次

    一般情况下在UITableView的header或cell中加载webview,需要动态计算webview的内容高度,然后刷新tableview,那么接下来问题的重点就是如何准确的拿到webview的内容高度了

    思路1:从WKWebview的加载完成代理方法中着手

    代码如下:

    - (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation {
        [webView evaluateJavaScript:@"document.body.offsetHeight" completionHandler:^(id _Nullable result,NSError * _Nullable error) {
            //1.获取页面高度,并重新计算webview的高度
            
            //2.缓存页面高度
    
           //3.tableview update 
        }];
    }
    

    但是,很可惜,这里获取的高度有时不精确,于是,采用了另一种方法。

    思路2:使用KVO监听webView.scrollView的contentSize

    code:
    cell的方法

    • cell初始化方法
    - (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
    {
        self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
        if (self) {
            UIView *superView = self.contentView;
            superView.backgroundColor = [UIColor blueColor];
            WKWebView *webView = [[WKWebView alloc] initWithFrame:superView.bounds];
            webView.scrollView.scrollEnabled = NO;//禁用webView滑动
            webView.scrollView.userInteractionEnabled = NO;
    //自适应宽高,这句要加
            webView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
           // webView.navigationDelegate = self;
            _webView = webView;
            [superView addSubview:_webView];
        //监听webView.scrollView的contentSize属性
            [_webView.scrollView addObserver:self forKeyPath:@"contentSize" options:NSKeyValueObservingOptionNew context:nil];
        }
        return self;
    }
    
    • KVO监听处理
    - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context
    {
        if ([keyPath isEqualToString:@"contentSize"]) {
            __weak typeof(self) weakSelf = self;
    //执行js方法"document.body.offsetHeight" ,获取webview内容高度
            [_webView evaluateJavaScript:@"document.body.offsetHeight" completionHandler:^(id _Nullable result, NSError * _Nullable error) {
                CGFloat contentHeight = [result floatValue];
                if (weakSelf.webHeightChangedCallback) {
                    weakSelf.webHeightChangedCallback(contentHeight);
                }
            }];
        }
    }
    
    • 移除kvo监听
    - (void)dealloc
    {
        [_webView.scrollView removeObserver:self forKeyPath:@"contentSize"];
    }
    
    • tableview部分
    - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
    {
        if (indexPath.row == 1) {
            return _webHeight;//web高度,全局属性
        }
        return 44;
    }
    
    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
    {
        if (indexPath.row == 1) {
            WebTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:NSStringFromClass(WebTableViewCell.class)];
            if (!cell) {
                cell = [[WebTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:NSStringFromClass(WebTableViewCell.class)];
            }
            __weak typeof(self) weakSelf = self;
            cell.webHeightChangedCallback = ^(CGFloat webHeight) {
                __strong typeof(self) strongSelf = weakSelf;
                if (strongSelf->_webHeight < webHeight) {//当缓存的高度小于返回的高度时,更新缓存高度,刷新tableview
                    strongSelf->_webHeight = webHeight;
                    [weakSelf.tableView beginUpdates];
                    [weakSelf.tableView endUpdates];
                }
            };
            return cell;
        }
        return nil;
    }
    
    //去除web页底部空白
    - (void)scrollViewDidScroll:(UIScrollView *)scrollView { // 判断webView所在的cell是否可见,如果可见就layout
        NSArray *cells = self.tableView.visibleCells;
        for (UITableViewCell *cell in cells) {
            if ([cell isKindOfClass:[WebTableViewCell class]]) {
                WebTableViewCell *webCell = (WebTableViewCell *)cell;
                [webCell.webView setNeedsLayout];
            }
        }
    }
    

    以上,就实现了tableview加载webview的操作。有不足之处,还请大家指正!

    相关文章

      网友评论

      • 凯文Kevin21:用KVO监听 WKWebView 的scrollView的contentSize属性,获取高度, 我第一次加载出网页loadRequest: 获取高度是对的, 后面切换了url ,换了个新的url, loadRequest: 获取高度还是原来url的高度,,高度不对。 代理回调方法都走了。

      本文标题:UITableView中加载WKWebView,高度计算问题

      本文链接:https://www.haomeiwen.com/subject/qrzogftx.html