iOS中webView嵌套tableView中动态高度问题

前言

在开发中,咱们可能遇到html网页的展现需求,为了让展示内容灵活多变,故不少新闻类的应用都是采用html+本地原生界面进行展现开发的。 从获取html源码开始提及吧!在拿到html源码的时候,咱们第一步要将这些网页内容展现到webView上面,显然,这一步很简单。若是整个页面单纯的是一个网页的话,基本就完工了,就是纯网页展现嘛!可是若是是webView嵌入到原生的页面中,好比将webView嵌入到tableView中,就会遇到一些问题。最很差解决的问题可能就是webView的高度问题了。html

方案

webView这个控件你们估计都知道,它是有内容高度的,就是contentSize,若是内容高度比控件的高度大的话,那么滚动的时候就是整个webView在滚动,而外层的tablView你会发现彷佛无法接收当前的滚动手势。这样其实形成了一个问题,就是原本要浏览tableView所要展现的内容,而结果却成了滚动webView了,是否是很奇怪,这样会影响用户体验。git

其实,解决的方法也很简单,只要将webView的contentSize的高度设置为webView的控件高度就能够了。这样就不会出现webView的内容滚动问题了。关键是如何设置这个内容高度,何时设置它比较合适。github

其实我尝试了不少种方案,好比在webView的代理回调中去实现高度的更新,可是代理中,只有一个webView内容所有加载完成之后的回调方法,若是在这个时候更新的话,会有很明显的跳跃效果,真的是很痛苦。由于网页的内容是实时变化的,若是在网页加载到最后的时候,在去更新它的高度,这个跳跃会更明显。而咱们所须要的其实就是实时更新网页内容的高度,只有这样才能作到像浏览网页同样浏览tablView中的webView。因此为了解决这个问题,我用了kvo,使用kvo监听网页内容的高度,若是高度发生变化,就去更新webView的控件高度,这样就作到了实时性,让网页的高度与网页内容的高度始终保持一致,这样其实就达到了咱们期待的效果。web

实现

就说说实现吧!代码奉上,哈哈~bash

- (void)creatView{

    self.webView = [[UIWebView alloc]initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, 300)];
    [self.webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"http://www.baidu.com"]]];
    
    //使用kvo为webView添加监听,监听webView的内容高度
    [self.webView.scrollView addObserver:self forKeyPath:@"contentSize" options:NSKeyValueObservingOptionOld | NSKeyValueObservingOptionNew context:nil];
    
    self.tableView = [[UITableView alloc]initWithFrame:self.view.frame style:UITableViewStyleGrouped];
    self.tableView.backgroundColor = [UIColor whiteColor];
    self.tableView.delegate = self;
    self.tableView.dataSource = self;
    self.tableView.rowHeight = 80;
    
    //设置webView为tableView的header
    self.tableView.tableHeaderView = self.webView;
    
    [self.view addSubview:self.tableView];
    
    
    

}
复制代码
//实时改变webView的控件高度,使其高度跟内容高度一致
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context{

    if ([keyPath isEqualToString:@"contentSize"]) {
        CGRect frame = self.webView.frame;
        frame.size.height = self.webView.scrollView.contentSize.height;
        self.webView.frame = frame;
        
        self.tableView.tableHeaderView = self.webView;
    }
}

- (void)dealloc{

    //销毁的时候别忘移除监听
    [self.webView.scrollView removeObserver:self forKeyPath:@"contentSize"];
}

#pragma -mark- tableView的代理方法
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{

    return 20;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
    
    static NSString *cellID = @"reuseCell";
    
    UITableViewCell *tableViewCell = [tableView dequeueReusableCellWithIdentifier:cellID];
    
    if (tableViewCell == nil) {
        tableViewCell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellID];
    }
    
    
    tableViewCell.textLabel.text = [NSString stringWithFormat:@"%ld",indexPath.row];
    
    return tableViewCell;

    
}

复制代码

对应的效果以下:ui

webView高度demo.gif

例子

点我看 Demo

相关文章
相关标签/搜索