在开发过程中,iOS 中实现加载 web 页面主要有两种控件,UIWebView 和 WKWebview,两种控件对应具体的实现方法不同。WKWebView是苹果公司在iOS8系统推出的,这里主要概述WebKit中更新的WKWebView控件的新特性与使用方法,以及小编在开发过程中踩的坑。
一、相比于UIWebView的优势:
- 在性能、稳定性、占用内存方面有很大提升;
- 允许JavaScript的Nitro库加载并使用(UIWebView中限制)
- 增加加载进度属性:estimatedProgress,不用在自己写假进度条了
- 支持了更多的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(0, 88, SCREEN_WIDTH, 2)]; ???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 >= 1){ ???????????[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)(.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ ???????????????????????????}); ???????} ???} ???else if ([keyPath isEqualToString:@"title"]){ ???????self.title = change[@"new"]; ???}}
这样就实现了对加载进度的显示了。
WKWebview的基本使用
原文地址:https://www.cnblogs.com/xjf125/p/10147928.html