WebView和H5的那点事

在iOS开发中好多时候,原生的app会很大的限制,也会有好多难以实现的东西。那就需要与H5进行混合开发,那就使用到了webView。
一、首先简单介绍一下webView:
1、三种加载方式:

- (void)loadRequest:(NSURLRequest *)request;//这是加载网页最常用的一种方式,通过一个网页URL来进行加载,这个URL可以是远程的也可以是本地的
- (void)loadHTMLString:(NSString *)string baseURL:(nullable NSURL *)baseURL;//这个方法需要将httml文件读取为字符串,其中baseURL是我们自己设置的一个路径,用于寻找html文件中引用的图片等素材。
- (void)loadData:(NSData *)data MIMEType:(NSString *)MIMEType textEncodingName:(NSString *)textEncodingName baseURL:(NSURL *)baseURL;//这个方式使用的比较少,但也更加自由,其中data是文件数据,MIMEType是文件类型,textEncodingName是编码类型,baseURL是素材资源路径。

2、一些常用的属性和变量

@property (nonatomic,assign)id  delegate;//设置webView的代理

@property (nonatomic,readonly,retain)UIScrollView *scrollView;//内置的scrollView

@property (nonatomic,readonly,retain)NSURLRequest *request;//URL请求

- (void)reload;//重新加载数据

- (void)stopLoading;//停止加载数据

- (void)goBack;//返回上一级

- (void)goForward;//跳转下一级

@property (nonatomic,readonly,getter=canGoBack)BOOL canGoBack;//获取能否返回上一级

@property (nonatomic,readonly,getter=canGoForward)BOOL canGoForward;//获取能否跳转下一级

@property (nonatomic,readonly,getter=isLoading)BOOL loading;//获取是否正在加载数据

- (NSString *)stringByEvaluatingJavaScriptFromString:(NSString *)script;//通过JavaScript操作web数据

@property (nonatomic)BOOL scalesPageToFit;//设置是否缩放到适合屏幕大小

@property (nonatomic)UIDataDetectorTypes dataDetectorTypesNS_AVAILABLE_IOS(3_0);//设置某些数据变为链接形式,这个枚举可以设置如电话号,地址,邮箱等转化为链接

@property (nonatomic)BOOL allowsInlineMediaPlaybackNS_AVAILABLE_IOS(4_0);//设置是否使用内联播放器播放视频

@property (nonatomic)BOOL mediaPlaybackRequiresUserActionNS_AVAILABLE_IOS(4_0);//设置视频是否自动播放

@property (nonatomic)BOOL mediaPlaybackAllowsAirPlayNS_AVAILABLE_IOS(5_0);//设置音频播放是否支持ari play功能

@property (nonatomic)BOOL suppressesIncrementalRenderingNS_AVAILABLE_IOS(6_0);//设置是否将数据加载如内存后渲染界面

@property (nonatomic)BOOL keyboardDisplayRequiresUserActionNS_AVAILABLE_IOS(6_0);//设置用户交互模式
@property (nonatomic)UIWebPaginationMode paginationModeNS_AVAILABLE_IOS(7_0);

    typedef NS_ENUM(NSInteger, UIWebPaginationMode) {
        UIWebPaginationModeUnpaginated,//不使用翻页效果
        UIWebPaginationModeLeftToRight,//将网页超出部分分页,从左向右进行翻页
        UIWebPaginationModeTopToBottom,//将网页超出部分分页,从上向下进行翻页
        UIWebPaginationModeBottomToTop,//将网页超出部分分页,从下向上进行翻页
        UIWebPaginationModeRightToLeft//将网页超出部分分页,从右向左进行翻页
    };

//这个属性用来设置一种模式,当网页的大小超出view时,将网页以翻页的效果展示,枚举如下:

@property (nonatomic)CGFloat pageLengthNS_AVAILABLE_IOS(7_0);//设置每一页的长度

@property (nonatomic)CGFloat gapBetweenPagesNS_AVAILABLE_IOS(7_0);//设置每一页的间距

@property (nonatomic,readonly)NSUInteger pageCountNS_AVAILABLE_IOS(7_0);//获取分页数

3、webView协议中的方法

- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType;//准备加载内容时调用的方法,通过返回值来进行是否加载的设置

- (void)webViewDidStartLoad:(UIWebView *)webView;//开始加载时调用的方法

- (void)webViewDidFinishLoad:(UIWebView *)webView;//结束加载时调用的方法

- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error;//加载失败时调用的方法

以上就是webView的属性、方法以及代理方法的简单解释。
二、简单给出一个例子:(加载一个京东的界面),直接上代码:

 self.webView = [[UIWebView alloc]initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)];
    self.webView.delegate = self;
    [self.view addSubview:self.webView];
    NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://www.jd.com"]];
    [self.webView loadRequest:request];

这里webView的加载请求,也可以像平时做网络请求一样进行设置“GET”或“POST”请求,这需要根据后台的需求。例如一个是用post请求的例子:
注:这里的HTTP_AFNETWORKING_POST_URLURL_Detail_H5([userManage key], _record_type, _record_id) 都是实际项目中的宏定义。

    _webView.frame = CGRectMake(0, 0, SCREEN_W, 0);
    _webView.delegate = self;
    NSURL *url = [NSURL URLWithString: HTTP_AFNETWORKING_POST_URL];
    NSString *body = URL_Detail_H5([userManage key], _record_type, _record_id);
    NSMutableURLRequest *request = [[NSMutableURLRequest alloc]initWithURL: url];
    [request setHTTPMethod: @"POST"];
    [request setHTTPBody: [body dataUsingEncoding: NSUTF8StringEncoding]];
    [self.webView loadRequest:request];

三、很多时候,webView加载了H5界面之后,如果H5界面过长,webView能进行滚动,但是有时需要进行让webView自适应,自适应的方法如下:
在网页加载完成的时候,使用stringByEvaluatingJavaScriptFromString实现UIWebView与JavaScript之间的交互,很方便的操作UIWebview中的页面元素。获取Html的高度。
虽然这个方法能使webView高度为显示的HTML实际高度,但效果并不是太好,当高度超出屏幕时,无法滚动下拉。但是这种方法与scrollview一起使用可以很好的控制滚动。

-(void)webViewDidFinishLoad:(UIWebView *)webView{
    NSInteger height = [[webView stringByEvaluatingJavaScriptFromString:@"document.body.scrollHeight"] integerValue];
    self.webView.frame=CGRectMake(0, 0, self.view.frame.size.width,height);
}

或者使用监听:

 [_webView.scrollView addObserver:self forKeyPath:@"contentSize" options:NSKeyValueObservingOptionNew context:nil];

 //监听
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
    if ([keyPath isEqualToString:@"contentSize"]) {
        NSInteger height = [[_webView stringByEvaluatingJavaScriptFromString:@"document.body.scrollHeight"] integerValue];
        self.webView.frame=CGRectMake(0, 0, self.view.frame.size.width,height);
        [self setUILayout];

    }
}

四、最后说与网页的交互。
很多时候我们需要监听用户点击了网页上的内容我们进行相应的跳转到原生的界面上,这里就使用到了webView代理方法中的

- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType

这个方法。网页中的每一个请求都会被触发这个方法,返回NO代表不执行这个请求(常用于JS与iOS之间通讯)。
还是以京东首页为例子,首先load一个京东界面,然后监听京东界面的京东超市那个请求,当发出这个请求,然后跳转到我们自己的原生界面。
效果图:
WebView和H5的那点事_第1张图片
WebView和H5的那点事_第2张图片
直接上代码:

#import "ViewController.h"
#import "aaa.h"

@interface ViewController ()<UIWebViewDelegate>

@property (strong, nonatomic) UIWebView *webView;

@property (strong, nonatomic) UIActivityIndicatorView *activityIndicatorView;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    self.webView = [[UIWebView alloc]initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)];
    self.webView.delegate = self;
    [self.view addSubview:self.webView];

    NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://www.jd.com"]];
    [self.webView loadRequest:request];

    self.activityIndicatorView = [[UIActivityIndicatorView alloc]initWithFrame:CGRectMake(0, 0, 32, 32)];
    self.activityIndicatorView.center = self.view.center;
    [self.activityIndicatorView setActivityIndicatorViewStyle:UIActivityIndicatorViewStyleWhiteLarge];
    [self.view addSubview:self.activityIndicatorView];

}
#pragma mark - **************** delegate
/**
 *  开始加载网页
 *
 *  @param webView
 */
-(void)webViewDidStartLoad:(UIWebView *)webView{
    NSLog(@"webViewDidStartLoad");
    [self.activityIndicatorView startAnimating];
}
/**
 *  网页加载完成的时候调用
 *
 *  @param webView
 */
-(void)webViewDidFinishLoad:(UIWebView *)webView{
    NSLog(@"webViewDidFinishLoad");
    [self.activityIndicatorView stopAnimating];
}
/**
 *  网页加载出错的时候调用
 *
 *  @param webView
 *  @param error
 */
-(void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error{
    if (error != nil) {
        NSLog(@"%@",[error description]);
    }
    [self.activityIndicatorView stopAnimating];
}
/**
 *   网页中的每一个请求都会被触发这个方法,返回NO代表不执行这个请求(常用于JS与iOS之间通讯)
 *
 *  @param webView
 *  @param request
 *  @param navigationType
 *
 *  @return
 */
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
    NSLog(@"ssss%@",request);
    if ([request.URL.absoluteString isEqualToString:@"http://pro.m.jd.com/2hqsQcyM5bEUVSStkN3BwrBHqVLd/index.html"] ) {
        aaa *aa = [[aaa alloc]init];
        [self presentViewController:aa animated:YES completion:nil];
        return NO;
    }
    return YES;
}
- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

@end

以上就是对webView的简单实用的总结。如有错误,请留言指出,将感激不尽。

微信公众号:不靠谱程序猿 微信公众号:Sheffi_Programmer
Github:Sheffi(https://github.com/goingmyway1) 新浪微博:Sheffi567
掘金:Sheffi(http://gold.xitu.io/user/57c13791128fe1005fc0b245)·

你可能感兴趣的:(iOS)