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