原理:
用UITableView做父视图(加入MJRefresh刷新,pods导入),原生的view当做tableView的头视图,把H5(UIWebView or WKWebView)当做控件,放在cell里,禁止滚动,在JS交互里动态改变cell的高度,刷新tableView。
上代码:
#import "WebViewController.h"
#import "MJRefresh.h"
#import
#import
@interface ViewController ()
{
UITableView *theTableView;
NSURLRequest *request; //H5链接
UIScrollView *scrollView; //WKWebView直接放在cell上会有显示不全的问题,不知道为啥,WKWebView放在scrollView上,scrollView再放在cell上
}
@property (nonatomic, strong) MJRefreshNormalHeader *theMJHeader; //MJ刷新
@property (nonatomic, assign)CGFloat cellHeight; //记录动态改变cell的高度
@property (nonatomic, strong) HomeHeaderView *headerView; //原生的view
@property (nonatomic, strong) UIWebView * webView;
@property (nonatomic, weak) JSContext * context; //UIWebView与JS交互
@property (nonatomic, strong) WKWebView *wkWebView;
@property (nonatomic, strong) WKWebViewConfiguration *configuration; //WKWebView与JS交互
@end
@implementation WebViewController
- (void)viewDidLoad{
[super viewDidLoad];
[self initUI];
[self refreshData]; // 请求数据
}
- (void)initUI{
theTableView = [[UITableView alloc]initWithFrame:CGRectMake(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT-64-49) style:UITableViewStylePlain];
theTableView.delegate = self;
theTableView.dataSource = self;
theTableView.showsVerticalScrollIndicator = NO;
theTableView.backgroundColor = [UIColor clearColor];
theTableView.separatorStyle = UITableViewCellSeparatorStyleNone;
//
UIView *view = [UIView new];
view.backgroundColor = [UIColor clearColor];
[theTableView setTableFooterView:view];
theTableView.tableHeaderView = self.headerView;
[self.view addSubview:theTableView];
theTableView.mj_header = self.theMJHeader;
NSString *URL = @“你的URL网址”;
request = [NSURLRequest requestWithURL:[NSURL URLWithString:URL]];
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ //可能web加载需要时间,0.5秒延时
if (CurrentiOS < 8.0) {
[_webView loadRequest:request];
}else{
[_wkWebView loadRequest:request];
}
});
}
#pragma mark ---- UITableViewDelegate
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return 1;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cellId"];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"cellId"];
if ([[[UIDevice currentDevice] systemVersion] floatValue] < 8.0 ) {
_webView = [[UIWebView alloc]initWithFrame:self.view.bounds];
_webView.backgroundColor = [UIColor whiteColor];
_webView.delegate = self;
_webView.scrollView.delegate = self;
_webView.scrollView.showsVerticalScrollIndicator = NO;//隐藏右侧滚动条
_webView.scrollView.scrollEnabled = NO;//web禁止滑动
[cell.contentView addSubview:_webView];
}else{
scrollView = [UIScrollView new];
scrollView.frame = self.view.bounds;
scrollView.scrollEnabled = NO;//scrollView禁止滑动
[cell.contentView addSubview:scrollView];
_wkWebView = [[WKWebView alloc]initWithFrame:self.view.bounds];
_wkWebView.navigationDelegate = self;
_wkWebView.scrollView.showsVerticalScrollIndicator = NO;//隐藏右侧滚动条
_wkWebView.scrollView.delegate = self;
_wkWebView.scrollView.scrollEnabled = NO;//web禁止滑动
[[_wkWebView configuration].userContentController addScriptMessageHandler:self name:@"AppModel"];//设置JS交互
[scrollView addSubview:_wkWebView];
}
}
return cell;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
return _cellHeight;
}
#pragma mark ---- UIWebViewDelegate
-(void)webViewDidFinishLoad:(UIWebView *)webView{
DLog(@"UIWebView----网页加载完毕");
[self.theMJHeader endRefreshing];
//获取js的运行环境
_context=[webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
_context[@"getAppData"] = ^(){
NSArray *array = [JSContext currentArguments];
NSDictionary *dic = [array[0] toDictionary];
//获取web页面传的参数,进行下一步操作,此处通过传出一个web的高度
//H5代码 getAppData(参数);本例的参数是一个json对象
[self toNextVCOFH5:dic andWebView:_webView];
};
}
-(void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error{
DLog(@"UIWebView----网页加载失败/超时");
[self.theMJHeader endRefreshing];
}
#pragma mark ---- WKNavigationDelegate, WKScriptMessageHandler
-(void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation{
DLog(@"WKWebView----网页加载完毕");
[self.theMJHeader endRefreshing];
}
-(void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message{
if ([message.name isEqualToString:@"AppModel"]) {
DLog(@"message.body ---- %@", message.body);
NSDictionary *dic = [message.body dictionaryForKey:@"body"];
//获取web页面传的参数,进行下一步操作,此处通过传出一个web的高度
//H5代码 window.webkit.messageHandlers.AppModel.postMessage(参数); 本例的参数是一个json对象
[self toNextVCOFH5:dic andWebView:_wkWebView];
}
}
- (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(null_unspecified WKNavigation *)navigation withError:(NSError *)error{
DLog(@"WKWebView----网页加载失败/超时");
[self.theMJHeader endRefreshing];
}
-(void)toNextVCOFH5:(NSDictionary *)dataDict andWebView:(id)webView{
CGFloat scale_screen = [UIScreen mainScreen].scale;//获取屏幕的像素比例
NSInteger height = [[dataDict stringForKey:@"value"] integerValue]/scale_screen;
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
_cellHeight = height;
if ([webView isKindOfClass:[UIWebView class]]) {
_webView.frame = CGRectMake(0, 0, theTableView.frame.size.width, _cellHeight);
}
if ([webView isKindOfClass:[WKWebView class]]) {
scrollView.frame = CGRectMake(0, 0, theTableView.frame.size.width, _cellHeight);
scrollView.contentSize = CGSizeMake(theTableView.frame.size.width, _cellHeight);
_wkWebView.frame = CGRectMake(0, 0, theTableView.frame.size.width, _cellHeight);
}
[theTableView reloadData];
});
}
//刷新web
-(void)theWebReload{
if (request.URL) {
if ([[[UIDevice currentDevice] systemVersion] floatValue] < 8.0 ) {
[self.webView loadRequest:request];
}else{
[self.wkWebView loadRequest:request];
}
}else{
NSString *URL =@“你的url”;
request = [NSURLRequest requestWithURL:[NSURL URLWithString:URL]];
if ([[[UIDevice currentDevice] systemVersion] floatValue] < 8.0 ) {
[self.webView loadRequest:request];
}else{
[self.wkWebView loadRequest:request];
}
}
}
#pragma mark ---- headerView & 懒加载
-(HeaderView *)headerView{
if (!_headerView) {
_headerView = [[HeaderView alloc]initWithFrame:CGRectMake(0, 0, SCREEN_WIDTH, 390)];
}
return _headerView;
}
- (MJRefreshNormalHeader *)theMJHeader{
if(!_theMJHeader){
@weakify(self);
_theMJHeader = [MJRefreshNormalHeader headerWithRefreshingBlock:^{
@strongify(self);
[self refreshData];
[self theWebReload]; //刷新web
}];
_theMJHeader.automaticallyChangeAlpha = YES;
_theMJHeader.lastUpdatedTimeLabel.hidden = YES;
}
return _theMJHeader;
}