iOS 原生嵌套H5,混合开发

原理:

用UITableView做父视图(加入MJRefresh刷新,pods导入),原生的view当做tableView的头视图,把H5(UIWebView or WKWebView)当做控件,放在cell里,禁止滚动,在JS交互里动态改变cell的高度,刷新tableView。


上代码:

#import "WebViewController.h"

#import "MJRefresh.h"

#import <JavaScriptCore/JavaScriptCore.h> //UIWebView的JS交互

#import  <WebKit/WebKit.h>

@interface ViewController ()<UITableViewDelegate, UITableViewDataSource, UIWebViewDelegate, WKNavigationDelegate, WKScriptMessageHandler>

{

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;

}

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,384评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,845评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,148评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,640评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,731评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,712评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,703评论 3 415
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,473评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,915评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,227评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,384评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,063评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,706评论 3 324
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,302评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,531评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,321评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,248评论 2 352

推荐阅读更多精彩内容

  • iOS开发系列--网络开发 概览 大部分应用程序都或多或少会牵扯到网络开发,例如说新浪微博、微信等,这些应用本身可...
    lichengjin阅读 3,654评论 2 7
  • 前言 关于UIWebView的介绍,相信看过上文的小伙伴们,已经大概清楚了吧,如果有问题,欢迎提问。 本文是本系列...
    CoderLF阅读 8,960评论 2 12
  • 1、禁止手机睡眠[UIApplication sharedApplication].idleTimerDisabl...
    DingGa阅读 1,117评论 1 6
  • iphone开发笔记 退回输入键盘 - (BOOL) textFieldShouldReturn:(id)text...
    爱易寒曲易散阅读 618评论 0 1
  • 百病成医,看来我患病的次数还不够多… 上礼拜傍晚,踏上滑板就屁颠屁颠的出去浪了,校内一路应该吸引不少眼球。嗯,之后...
    夕影西逝阅读 224评论 0 0