众所周知iOS8后苹果增加了WKWebView,在这之前大家使用的都是UIWebView,刚出来之后我也一直在使用UIWebView,最近听说UIWebView以后会过期,所以本文以WKWeBView为例
实现原理:
自定义UITableViewCell, cell上添加scrollView,再将WKWebView添加到scrollView,通过KVO监听webView.scrollView的contentSize值的变化来获取scrollView的高度,从而更新tableViewCell的行高
实现细节:
为了让web页面中的元素都适应屏幕的宽度显示,需要对WKWebView进行一下设置,原理是加载js代码,然后通过js来设置webview中的元素大小:
实现过程:
//
// ViewController.m
// HQWebView
//
// Created by admin on 2017/7/18.
// Copyright © 2017年 judian. All rights reserved.
//
#import "ViewController.h"
#import <WebKit/WebKit.h>
@interface ViewController ()<UITableViewDelegate, UITableViewDataSource, WKUIDelegate, WKNavigationDelegate>
@property (nonatomic, strong) UITableView *tableView;
@property (nonatomic, strong) UIScrollView *scrollView;
@property (nonatomic, strong) WKWebView *webView;
@property (nonatomic, assign) CGFloat webViewHeight;
@end
static NSString *reuseDefaultCell = @"DefaultCell";
static NSString *reuseWebCell = @"WebCell";
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.webViewHeight = 0.0;
[self creatWebView];
self.tableView = [[UITableView alloc] initWithFrame:self.view.frame style:UITableViewStylePlain];
self.tableView.delegate = self;
self.tableView.dataSource = self;
self.tableView.showsHorizontalScrollIndicator = NO;
self.tableView.showsVerticalScrollIndicator = NO;
self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
[self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:reuseWebCell];
[self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:reuseDefaultCell];
[self.view addSubview:self.tableView];
}
#pragma mark -------创建webView-------
- (void)creatWebView {
WKWebViewConfiguration *wkWebConfig = [[WKWebViewConfiguration alloc] init];
WKUserContentController *wkUController = [[WKUserContentController alloc] init];
wkWebConfig.userContentController = wkUController;
//自适应屏幕的宽度js
NSString *jSString = @"var meta = document.createElement('meta'); meta.setAttribute('name', 'viewport'); meta.setAttribute('content', 'width=device-width'); document.getElementsByTagName('head')[0].appendChild(meta);";
WKUserScript *wkUserScript = [[WKUserScript alloc] initWithSource:jSString injectionTime:WKUserScriptInjectionTimeAtDocumentEnd forMainFrameOnly:YES];
//添加js调用
[wkUController addUserScript:wkUserScript];
self.webView = [[WKWebView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, 1) configuration:wkWebConfig];
self.webView.backgroundColor = [UIColor clearColor];
self.webView.opaque = NO;
self.webView.userInteractionEnabled = YES;
self.webView.scrollView.bounces = NO;
self.webView.UIDelegate = self;
self.webView.navigationDelegate = self;
[self.webView sizeToFit];
//监听webView contentSize 值得变化
[self.webView.scrollView addObserver:self forKeyPath:@"contentSize" options:NSKeyValueObservingOptionNew context:nil];
NSURL *url = [NSURL URLWithString:@"https://www.baidu.com"];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
[self.webView loadRequest:request];
self.scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, 1)];
[self.scrollView addSubview:self.webView];
}
#pragma 监听webView contentSize 值的变化
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context {
if ([keyPath isEqualToString:@"contentSize"]) {
//方法一
UIScrollView *scrollView = (UIScrollView *)object;
CGFloat height = scrollView.contentSize.height;
self.webViewHeight = height;
self.webView.frame = CGRectMake(0, 0, self.view.frame.size.width, height);
self.scrollView.frame = CGRectMake(0, 0, self.view.frame.size.width, height);
self.scrollView.contentSize = CGSizeMake(self.view.frame.size.width, height);
[self.tableView reloadRowsAtIndexPaths:[NSArray arrayWithObjects:[NSIndexPath indexPathForRow:3 inSection:0], nil] withRowAnimation:UITableViewRowAnimationNone];
/*
//方法二
[_webView evaluateJavaScript:@"document.body.offsetHeight" completionHandler:^(id _Nullable result, NSError * _Nullable error) {
CGFloat height = [result doubleValue] + 20;
self.webViewHeight = height;
self.webView.frame = CGRectMake(0, 0, self.view.frame.size.width, height);
self.scrollView.contentSize = CGSizeMake(self.view.frame.size.width, height);
[self.tableView reloadRowsAtIndexPaths:[NSArray arrayWithObjects:[NSIndexPath indexPathForRow:3 inSection:0], nil] withRowAnimation:UITableViewRowAnimationNone];
}];
*/
}
}
#pragma mark -------UItableViewDelegate-------
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return 15;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
switch (indexPath.row) {
case 3:
return _webViewHeight;
break;
default:
return 50;
break;
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
switch (indexPath.row) {
case 3: {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:reuseWebCell];
[cell.contentView addSubview:self.scrollView];
return cell;
}
break;
default: {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:reuseDefaultCell];
cell.textLabel.text = [NSString stringWithFormat:@"普通cell, 编号:%ld", indexPath.row];
return cell;
}
break;
}
}
@end
github下载地址:https://github.com/yanhaiqiang/HQWebViewFit.git 别忘了给个star啊