本文主要讲述OC调用JS的内部的方法,和用JS来调用OC的方法,由于代码中已经加了注释,所以不再赘述。在这里用本地 HTML 文件作为说明,HTML文件如下:
charset="utf-8">
name="viewport"
content="width=device-width,initial-scale=1,minimum-scale=1, maximum-scale=1, user-scalable=no">
#TopView{
display: block;
height: 60px;
line-height: 60px;
color:#FFFFF0;
margin: 0px auto;
background: #4169E1;
text-align: center;
font-size: 30px;
}
.box li{list-style:none;display:inline-block;}
@media(min-screen:320px) and (max-screen:375px){#mying{height:150px;}
}
#myimg{
max-width:200px;
}
#myimg img{
width:100%
}
id="myimage"> src="" alt="">
id= "button">会改变的段落
id= "button1">有参数的改变
id= "AddPfromOC"> 订单 我的 渠道管理 商户管理 class="ul1">
#import "ViewController.h"
#import
@interface ViewController ()<UIWebViewDelegate> {
UIWebView *_web;
}
@property(nonatomic,weak) JSContext *context;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// 创建视图
[self creatUI];
}
#pragma mark - 创建 web 视图
-(void)creatUI{
// 创建
_web = [[UIWebView alloc]initWithFrame:self.view.bounds];
_web.backgroundColor = [UIColor yellowColor];
_web.delegate = self;
[self.view addSubview:_web];
// 加载出来本地的 HTML 文件
NSURL *url = [[NSBundle mainBundle]URLForResource:@"Test" withExtension:@"html"];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
[_web loadRequest:request];
// 创建两个按钮,用来调用 js 内部的方法
UIButton *btn1 =[UIButton buttonWithType:UIButtonTypeCustom];
btn1.frame = CGRectMake(0, 500, 200, 40);
btn1.backgroundColor = [UIColor yellowColor];
[btn1 setTitle:@"oc调用无参数js" forState:UIControlStateNormal];
[btn1 setTitleColor:[UIColor redColor] forState:UIControlStateNormal];
[btn1 addTarget:self action:@selector(btn1click) forControlEvents:UIControlEventTouchUpInside];
UIButton *btn2 = [UIButton buttonWithType:UIButtonTypeCustom];
btn2.frame = CGRectMake(0, 580, 200, 40);
btn2.backgroundColor = [UIColor greenColor];
[btn2 setTitle:@"oc调用有参数js" forState:UIControlStateNormal];
[btn2 setTitleColor:[UIColor redColor] forState:UIControlStateNormal];
[btn2 addTarget:self action:@selector(btn2click) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:btn1];
[self.view addSubview:btn2];
}
#pragma mark - OC的按钮开始调用JS
/**
OC 调用 JS 的方法里面 ,通用的方法是:
[_web stringByEvaluatingJavaScriptFromString:@"这里写JS的方法名字"];
如果无参数,就像第一个按钮写的那样
如果有参数,就像第二个按钮写的那样
当然,得事先知道 js 里面对应的方法是怎么写的。。
*/
// 按钮1
-(void)btn1click{
[_web stringByEvaluatingJavaScriptFromString:@"buttonclick()"];
}
// 按钮2
-(void)btn2click{
NSString *name = @"Kean";
NSString *number = @"is666";
NSString *str = [NSString stringWithFormat:@"buttonclick1('%@','%@')",name,number];
[_web stringByEvaluatingJavaScriptFromString:str];
}
#pragma mark - webView 的代理方法的实现
-(BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
// 开始相应请求触发
return YES;
}
-(void)webViewDidStartLoad:(UIWebView *)webView{
// 开始加载网页
}
#pragma mark - JS 调用 OC 的方法
/**
JS 调用 OC 的方法
总体来说就是,我通过 JSContext ,来获取到 JS 的上下文信息,然后通过上下文和对应的JS中的回调方法,在回调方法里面实现对OC的控制,下面来说具体步骤:
1. 获取上下文信息
_context = [webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
2.1 无返回值的类型
_context[@"JS中回调方法的名字"] = ^(){
在该 block 块里面,可以用OC的代码,来做你想要做的事情...
};
2.2 有返回值的类型
_context[@"JS中回调方法的名字"] = ^(){
在该 block 块里面,可以用OC的代码,来做你想要做的事情...
除此之外,可以获取到 JS 返回值...
不过得事先知道返回值是什么,有几个
// (1).获取存放有返回值的数组
NSArray *args = [JSContext currentArguments];
// (2)从数组中取到的元素是 JSValue 类型的
JSValue *name = args[0];
// (3)转化成字符串?好的
NSString *nameStr = name.toString;
// 如果你需要的话,就可以使用 JS 中的特定的返回值 nameStr 了;
};
*/
-(void)webViewDidFinishLoad:(UIWebView *)webView{
// 向js中插入一段代码
NSString *str = @"document.getElementById('AddPfromOC').innerHTML = '这段文字是由oc加入的js代码,在网页加载完成的时候加入';";
[webView stringByEvaluatingJavaScriptFromString:str];
// 加载完毕
_context = [webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
_context[@"jscall1"] = ^(){
[self changenav];
};
_context[@"jscall2"] = ^(){
// 这里需要对数据操作
NSArray *args = [JSContext currentArguments];
// 获取
JSValue *nameValue = args[0];
JSValue *numValue = args[1];
// 类型的转化
NSString *name = nameValue.toString;
NSString *num = numValue.toString;
[self changenavwith:name and:num];
};
_context[@"jscall3"] = ^(){
NSArray *args = [JSContext currentArguments];
JSValue *block = args[2];
NSString *str = block.toString;
[self isOKwith:str];
};
}
-(void)isOKwith:(NSString *)block{
if ([block isEqualToString:@"bolck"]) {
[self button3success:block];
}else{
[self button3error:block];
}
}
#pragma mark - JS 调用 OC 之后,OC 再次调用 JS 的方法(弹出框的方法)
-(void)button3success:(NSString *)block{
NSString *str = [NSString stringWithFormat:@"jscallblock('校验成功%@')",block];
[_web stringByEvaluatingJavaScriptFromString:str];
}
-(void)button3error:(NSString *)block{
NSString *str = [NSString stringWithFormat:@"jscallblock('校验失败%@')",block];
[_web stringByEvaluatingJavaScriptFromString:str];
}
#pragma mark - JS 调用 OC 之后,自定义改变导航的方法
-(void)changenav{
self.navigationItem.title =@"无参数方法调用";
}
-(void)changenavwith:(NSString *)name and:(NSString *)number{
self.navigationItem.title =[NSString stringWithFormat:@"姓名%@,密码%@",name,number];
}