UIWebView
什么是UIWebView
- UIWebView是iOS内置的浏览器控件
- 系统自带的Safari浏览器就是通过UIWebView实现的
UIWebView不但能加载远程的网页资源,还能家在绝大部分的常见文件
- HTML\HTM
- PDF,DOC,PPT,TXT
- MP4
- ... ...
网页内容缩放到整个设备
// 自动缩放到占据设置内容
self.webView.scalesPageToFit = YES;
完成的网页组成
- HTML:内容(文字,图片)
- CSS:美化,样式
- JS:动态效果,处理事件(跟用户进行交互)
OC中打电话
- (void)call {
UIApplication * app = [UIApplication sharedApplication];
[app openURL:[NSURL URLWithString:@"tel://10086"]];
}
基本操作
#import "ViewController.h"
@interface ViewController ()<UIWebViewDelegate>
@property (weak, nonatomic) IBOutlet UIWebView *webView;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// 代理能够监听网络加载的过程
self.webView.delegate = self;
[self.webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"http://www.baidu.com"]]];
}
#pragma mark - UIWebViewDelegate
- (void)webViewDidStartLoad:(UIWebView *)webView {
}
- (void)webViewDidFinishLoad:(UIWebView *)webView {
}
- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error {
}
/**
* 每当webView即将发送请求之前,都会调用这个方法
* 返回YES:告诉webView允许加载这个请求
* 返回NO:告诉webView不允许加载这个请求(可以拦截操作)
*/
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
// request.URL.absoluteString 将URL转成字符串
if ([request.URL.absoluteString containsString:@"life"]) return NO;
return YES;
}
@end
加载HTML
[self.webView loadHTMLString:@"<html><body>这个是测试问价</body></html>" baseURL:nil];
加载HTML中各种数据
// 代理能够监听网络加载的过程
self.webView.delegate = self;
// 自动检测特殊信息(检测类型,各种特殊的字符串,网站,电话等)
self.webView.dataDetectorTypes = UIDataDetectorTypeAll;
// 自己新建的一个HTML文件
[self.webView loadRequest:[NSURLRequest requestWithURL:[[NSBundle mainBundle] URLForResource:@"test" withExtension:@"html"]]];
加载视频数据
[self.webView loadRequest:[NSURLRequest requestWithURL:[NSURL fileURLWithPath:@"/Users/yuezuo/Desktop/test.mp4"]]];
加载excel文件
[self.webView loadRequest:[NSURLRequest requestWithURL:[NSURL fileURLWithPath:@"/Users/yuezuo/Desktop/test.xlsx"]]];
JS简单交互
#import "ViewController.h"
@interface ViewController ()<UIWebViewDelegate>
@property (weak, nonatomic) IBOutlet UIWebView *webView;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// 代理能够监听网络加载的过程
self.webView.delegate = self;
// 自动检测特殊信息(检测类型,各种特殊的字符串,网站,电话等)
self.webView.dataDetectorTypes = UIDataDetectorTypeAll;
[self.webView loadRequest:[NSURLRequest requestWithURL:[[NSBundle mainBundle] URLForResource:@"test" withExtension:@"html"]]];
}
#pragma mark - UIWebViewDelegate
// 当网页加载完成之后,调用webView的JavaScript代码
- (void)webViewDidFinishLoad:(UIWebView *)webView {
[webView stringByEvaluatingJavaScriptFromString:@"alert(100)"];
}
@end
- HTML内容
<html>
<!-- 网页的描述信息 -->
<head>
<meta charset="UTF-8">
</head>
<!-- 网页的具体内容 -->
<body>
电话:10086
<button style="background: red; width:100px; height:30px;>Call</button>
</body>
</html>
- 执行效果
- 点击之后的效果
改进之后获取网页标题
- HTML文件中改动
<html>
<!-- 网页的描述信息 -->
<head>
<meta charset="UTF-8">
<!-- 网页的标题,在浏览器中可以看到,但是在手机上好像看不到 -->
<title>第一个网页</title>
</head>
<!-- 网页的具体内容 -->
<body>
电话:10086
<button style="background: red; width:100px; height:30px;" onclick="alert(document.title);">Call</button>
</body>
</html>
主要是添加了:"onclick="alert(document.title);"
在OC中调用JS获取标题
#pragma mark - UIWebViewDelegate
- (void)webViewDidFinishLoad:(UIWebView *)webView {
// 执行完成之后获取HTML的标题
NSString * title = [webView stringByEvaluatingJavaScriptFromString:@"document.title"];
NSLog(@"%@",title);
}
HTML中函数
<html>
<!-- 网页的描述信息 -->
<head>
<meta charset="UTF-8">
<!-- 网页的标题,在浏览器中可以看到,但是在手机上好像看不到 -->
<title>第一个网页</title>
<script>
function login ()
{
return 10;
}
</script>
</head>
<!-- 网页的具体内容 -->
<body>
电话:10086
<button style="background: red; width:100px; height:30px;" onclick="alert(login());">Call</button>
</body>
</html>
// 这里是不用写返回值,但是可以在函数中写,调用的时候就直接使用login()即可。 <script> function login () { return 10; } </script>
oc调用JS中函数
- (void)webViewDidFinishLoad:(UIWebView *)webView {
// 执行完成之后获取HTML的标题
NSString * login = [webView stringByEvaluatingJavaScriptFromString:@"login();"];
NSLog(@"%@",login);
}
JS中调用OC
// 主要定义了location.href = 'jx://call';这个虚假的协议,当做我们在oc中获取标识。
<html>
<!-- 网页的描述信息 -->
<head>
<meta charset="UTF-8">
<!-- 网页的标题,在浏览器中可以看到,但是在手机上好像看不到 -->
<title>第一个网页</title>
<script>
function login ()
{
location.href = 'jx://call';
}
</script>
</head>
<!-- 网页的具体内容 -->
<body>
电话:10086
<button style="background: red; width:100px; height:30px;" onclick="login();">Call</button>
</body>
</html>
在oc中代码
/**
* 这个方法中来完成JS调用OC
* 第三方框架:WebViewJavaScriptBridge完成js与oc交互
*/
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
NSString * url = request.URL.absoluteString;
NSString * scheme = @"jx://";
if ([url hasPrefix:scheme]) {
NSLog(@"想要调用OC的方法,因为压根没有这个协议");
NSString * methodName = [url substringFromIndex:scheme.length];
NSLog(@"%@",methodName);
[self performSelector:NSSelectorFromString(methodName) withObject:nil];
return NO;
}
NSLog(@"想加载其他请求,不是加载oc本地的方法");
return YES;
}
- (void)call {
NSLog(@"JS中调用OC 方法");
}
但是代码中是有缺陷的,因为我们没法传递参数
JS中调用OC传递参数
<html>
<!-- 网页的描述信息 -->
<head>
<meta charset="UTF-8">
<title>第一个网页</title>
<script>
function login()
{
// 让webView跳转到百度页面(加载百度页面)
location.href = 'xmg://sendMessage_number2_number3_?100&100&99';
}
</script>
</head>
<!-- 网页的具体内容 -->
<body>
电话:10086
<button style="background: red; width:100px; height:30px;" onclick="login();">Call</button>
<br>
<a href="http://www.baidu.com">百度</a>
</body>
</html>
oc中代码
#pragma mark - <UIWebViewDelegate>
/**
* 通过这个方法完成JS调用OC
* JS和OC交互的第三方框架:WebViewJavaScriptBridge
*/
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
// url == xmg://sendMessage_?200
NSString *url = request.URL.absoluteString;
NSString *scheme = @"xmg://";
if ([url hasPrefix:scheme]) {
// 获得协议后面的路径 path == sendMessage_number2_?200&300
NSString *path = [url substringFromIndex:scheme.length];
// 利用?切割路径
NSArray *subpaths = [path componentsSeparatedByString:@"?"];
// 方法名 methodName == sendMessage:number2:
NSString *methodName = [[subpaths firstObject] stringByReplacingOccurrencesOfString:@"_" withString:@":"];
// 参数 200&300
NSArray *params = nil;
if (subpaths.count == 2) {
params = [[subpaths lastObject] componentsSeparatedByString:@"&"];
}
// 调用
[self performSelector:NSSelectorFromString(methodName) withObjects:params];
return NO;
}
NSLog(@"想加载其他请求,不是想调用OC的方法");
return YES;
}
@end