在开发过程中,iOS 中实现加载 web 页面主要有两种控件,UIWebView 和 WKWebview,两种控件对应具体的实现方法不同。WKWebView是苹果公司在iOS8系统推出的,这里主要概述WebKit中更新的WKWebView控件的新特性与使用方法,以及小编在开发过程中踩的坑。

一、相比于UIWebView的优势:

  1. 在性能、稳定性、占用内存方面有很大提升;
  2. 允许JavaScript的Nitro库加载并使用(UIWebView中限制)
  3. 增加加载进度属性:estimatedProgress,不用在自己写假进度条了
  4. 支持了更多的HTML的属性

二、WKWebview的常用属性

@property (nullable, nonatomic, readonly, copy) NSString *title;

@property (nullable, nonatomic, readonly, copy) NSURL *URL;

@property (nonatomic, readonly, getter=isLoading) BOOL loading;
//加载进度
@property (nonatomic, readonly) double estimatedProgress;

三、WKWebview的常用方法

- (nullable WKNavigation *)loadRequest:(NSURLRequest *)request;

- (nullable WKNavigation *)loadFileURL:(NSURL *)URL allowingReadAccessToURL:(NSURL *)readAccessURL API_AVAILABLE(macosx(10.11), ios(9.0));

- (nullable WKNavigation *)loadHTMLString:(NSString *)string baseURL:(nullable NSURL *)baseURL;

- (nullable WKNavigation *)loadData:(NSData *)data MIMEType:(NSString *)MIMEType characterEncodingName:(NSString *)characterEncodingName baseURL:(NSURL *)baseURL API_AVAILABLE(macosx(10.11), ios(9.0));

四、WKNavigationDelegate代理的方法

#pragma mark - WKNavigationDelegate
/* 页面开始加载 */
- (void)webView:(WKWebView *)webView didStartProvisionalNavigation:(WKNavigation *)navigation{
NSLog(@"页面开始加载");
}
/* 开始返回内容 */
- (void)webView:(WKWebView *)webView didCommitNavigation:(WKNavigation *)navigation{
NSLog(@"开始返回内容");
}
/* 页面加载完成 */
- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation{
NSLog(@"页面加载完成");
}
/* 页面加载失败 */
- (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(WKNavigation *)navigation{
NSLog(@"页面加载失败");
}
/* 在发送请求之前,决定是否跳转 */
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler{
//允许跳转
decisionHandler(WKNavigationActionPolicyAllow);
//不允许跳转
//decisionHandler(WKNavigationActionPolicyCancel);
}
/* 在收到响应后,决定是否跳转 */
- (void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler{ NSLog(@"%@",navigationResponse.response.URL.absoluteString);
//允许跳转
decisionHandler(WKNavigationResponsePolicyAllow);
//不允许跳转
//decisionHandler(WKNavigationResponsePolicyCancel);
}

五、小编的实例Demo

首先遵守协议:

<WKUIDelegate, WKNavigationDelegate>

其次创建一个WKWebView

#pragma mark - 创建webView
- (void)createWebView{ WKWebViewConfiguration *config = [[WKWebViewConfiguration alloc] init];
config.selectionGranularity = WKSelectionGranularityDynamic;
config.allowsInlineMediaPlayback = YES;
WKPreferences *preferences = [WKPreferences new];
//是否支持JavaScript
preferences.javaScriptEnabled = YES;
//不通过用户交互,是否可以打开窗口
preferences.javaScriptCanOpenWindowsAutomatically = YES;
config.preferences = preferences;
self.webView = [[WKWebView alloc] initWithFrame:self.view.bounds];
[self.view addSubview:self.webView]; /* 加载服务器url的方法*/
NSString *url = @"https://www.baidu.com";
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:url]];
[self.webView loadRequest:request]; self.webView.navigationDelegate = self;
self.webView.UIDelegate = self; }

这样就可以在webView中正常加载百度首页了。

不过,在开发中有时遇到网络不佳的时候,想给用户显示一个加载网页的进度,加载完成后,想再navigation中显示网页的标题,就需要对WKWebView的"estimatedProgress"和

"title"进行监听了。

首先创建一个进度条

- (void)createProgressView{
self.progressView = [[UIProgressView alloc] initWithFrame:CGRectMake(, , SCREEN_WIDTH, )];
self.progressView.progressViewStyle = UIProgressViewStyleDefault;
self.progressView.tintColor = [UIColor blueColor];
self.progressView.trackTintColor = [UIColor greenColor];
[self.view addSubview:self.progressView];
}

让webView对“进度”和“标题”进行监听

[self.webView addObserver:self forKeyPath:@"estimatedProgress" options:NSKeyValueObservingOptionNew context:nil];
[self.webView addObserver:self forKeyPath:@"title" options:NSKeyValueObservingOptionNew context:NULL];

最后,完成对KVO的回调

#pragma mark - KVO回馈
-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context{
if ([keyPath isEqualToString:@"estimatedProgress"]) {
double progress = _webView.estimatedProgress;
self.progressView.alpha = 1.0f;
[self.progressView setProgress:progress animated:YES];
if(progress >= ){
[UIView animateWithDuration:0.25 delay:0.25 options:UIViewAnimationOptionCurveEaseOut animations:^{
self.progressView.alpha = 0.0f;
} completion:^(BOOL finished) {
[self.progressView setProgress:0.0f animated:NO];
}];
}
if ([change[@"new"] floatValue] <[change[@"old"] floatValue]) {
return;
}
if ([change[@"new"]floatValue] == 1.0) {
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(. * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ });
}
}
else if ([keyPath isEqualToString:@"title"]){
self.title = change[@"new"];
}
}

这样就实现了对加载进度的显示了。

最新文章

  1. JavaScript权威设计--Window对象之Iframe(简要学习笔记十四)
  2. 分布式一致性算法--Paxos
  3. [c#]一个窗体调用另一个窗体的事件
  4. URAL 1244. Gentlemen(DP)
  5. 用友的凭证update
  6. thinkpad E450 fn快捷键设置
  7. Android 手机技巧
  8. CentOS 6.5上MySQL安装部署与入门。
  9. cocos2d 3.0自定义事件答疑解惑
  10. STL中的单向队列queue
  11. spring junit参数
  12. Ubuntu14.04 和 Windows7 双系统安装
  13. CodeSmith使用总结--下拉列表和文件夹对话框属性
  14. 谁在唱衰PC?说出你的理由
  15. Spring两种代理区别
  16. Spring中bean实例化的三种方式
  17. Java中的RASP实现
  18. 23命令模式Command
  19. redis集群的ruby环境
  20. C#简述(二)

热门文章

  1. 自定义实现wcf的用户名密码验证
  2. WPF命令绑定 自定义命令
  3. poj 3686(拆点+最小权匹配)
  4. jmeter对响应结果做正则、json、xpath结果测试
  5. 用训练好的caffemodel对单个/批量图片进行分类
  6. servlet;jsp;cookies;session
  7. 【BZOJ2384】[Ceoi2011]Match KMP
  8. Android输入法的显示与隐藏
  9. UI中各种手势的使用点击,捏合,清扫,旋转,平移,边缘移动,长按
  10. width: 50%; display:inline-flex;