ios wkwebview弹框_iOS WKWebView的使用

级别:★☆☆☆☆

标签:「WKWebView」「WKWebView加载新页面失败」「WKWebView 弹框没有显示」「WKWebView 打开其他应用」

作者: WYW

审校: QiShare团队

前言:

笔者最近了解了部分关于WKWebView的内容,将会在本文中说明关于WKWebView基本使用的内容。 WKWebView是一个展示交互式web内容的视图,支持iOS8.0及macOS10.10以上的系统。

本文涉及内容包括WKWebView展示Html、使用WKWebView时可能用到的API、WKWebView 加载新页面、WKWebView正常显示JS弹框、WKWebView截图。

笔者做了2个效果图如下:

第一个效果图展示了WKWebView加载url,及相关返回、前进、重新加载、查看backForwardList中item信息、截图等API效果。

QiWKWebView1.gif

第二个效果图展示了WKWebView加载本地Html 文件,及相关加载新页面、弹出alert弹框、打开其他应用的内容。

QiWKWebView2.gif

一、WKWebView加载html

加载网络url

WKWebViewConfiguration *webConfiguration = [WKWebViewConfiguration new];

_webView = [[WKWebView alloc] initWithFrame:[UIScreen mainScreen].bounds configuration:webConfiguration];

NSString *urlStr = @"https://www.so.com";

NSURL *url = [NSURL URLWithString:urlStr];

NSURLRequest *request = [[NSURLRequest alloc] initWithURL:url];

[_webView loadRequest:request];

复制代码

加载本地html

WKWebViewConfiguration *webConfig = [WKWebViewConfiguration new];

webConfig.dataDetectorTypes = WKDataDetectorTypePhoneNumber;

_webView = [[WKWebView alloc] initWithFrame:CGRectZero configuration:webConfig];

_webView.allowsBackForwardNavigationGestures = YES;

_webView.backgroundColor = [UIColor whiteColor];

self.view = _webView;

[_webView loadFileURL:[[NSBundle mainBundle] URLForResource:@"QiLink" withExtension:@"html"] allowingReadAccessToURL:[[NSBundle mainBundle] bundleURL]];

/* // 或者使用如下方式

NSString *localHtmlStr = [[NSString alloc] initWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"QiLink" ofType:@"html"] encoding:NSUTF8StringEncoding error:nil];

[_webView loadHTMLString:localHtmlStr baseURL:[[NSBundle mainBundle] bundleURL]];

*/

复制代码

二、WKWebView可能用到的API

allowsBackForwardNavigationGestures

允许左滑右滑,默认值为NO;设置为YES后,即可实现左右滑手势可用。

_webView.allowsBackForwardNavigationGestures = YES;

goForward

goForward可以向前导航到back-forward列表中的内容,相当于回到关闭的之前看过的详情界面。

if ([_webView canGoForward]) {

[_webView goForward];

}

复制代码

goBack

goBack可以向后导航到back-forward列表中的内容,相当于返回。

if ([_webView canGoBack]) {

[_webView goBack];

}

复制代码

backForwardList

WKWebView的backForwardList,这里可以列表中条目的标题及url等信息。

if (_webView.backForwardList.forwardList.count > 0) {

NSLog(@"forwardItem");

NSLog(@"title:%@", _webView.backForwardList.forwardItem.title);

NSLog(@"URL:%@", _webView.backForwardList.forwardItem.URL);

}

if (_webView.backForwardList.backList.count > 0) {

NSLog(@"backwardItem");

NSLog(@"title:%@", _webView.backForwardList.backItem.title);

NSLog(@"URL:%@", _webView.backForwardList.backItem.URL);

}

复制代码

reload

如出现Html内容未正常显示的问题,可用[_webView reload];刷新WKWebView,重新加载Html的内容。

截图takeSnapshotWithConfiguration

如需截取当前显示在屏幕中的WKWebView的图片,可以使用

WKSnapshotConfiguration *snapConfig = [[WKSnapshotConfiguration alloc] init];

[_webView takeSnapshotWithConfiguration:snapConfig completionHandler:^(UIImage * _Nullable snapshotImage, NSError * _Nullable error) {

if (!error) {

NSLog(@"%@", snapshotImage);

UIImageWriteToSavedPhotosAlbum(snapshotImage, self, @selector(image:didFinishSavingWithError:contextInfo:), nil);

} else {

NSLog(@"error:%@", error);

}

}];

复制代码

三、WKWebView 加载新页面

笔者了解的实现Html中点击链接后加载新页面的方式有:

self so.com

parent so.com

top so.com

blank 打开so.com

window 打开so.com

复制代码

笔者把上边几种方式分为3类,使用href的方式打开的和使用js打开的html界面。

使用href方式打开的界面就分为target="blank"的与其他。

href方式打开新页面

target="_blank"

blank 打开so.com

复制代码

target="_blank"相当于在新标签页打开一个新页面,需要在WKWebView的WKNavigationDelegate代理方法中处理导航切换的loadRequest请求。

#pragma mark - WKUIDelegate

// Decides whether to allow or cancel a navigation.

- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler {

NSLog(@"%@", webView.URL);

NSLog(@"%@", navigationAction.request.URL);

NSURL *url = navigationAction.request.URL;

if ([url.absoluteString hasPrefix:@"http"]) {

// The target frame, or nil if this is a new window navigation.

if (!navigationAction.targetFrame) {

[webView loadRequest:navigationAction.request];

}

decisionHandler(WKNavigationActionPolicyAllow);

} else {

decisionHandler(WKNavigationActionPolicyAllow);

}

}

复制代码

target非"_blank"

target非"_blank"相当于在当前页面加载新的url,WKWebView可以可以正常加载url。

js打开新页面

window 打开so.com

复制代码

使用js的window.open打开新页面,需要在WKWebView的UIDelegate代理方法中处理导航切换的loadRequest请求。

#pragma mark - WKUIDelegate

// creates a new web view.

// The web view returned must be created with the specified configuration. WebKit loads the request in the returned web view.

- (WKWebView *)webView:(WKWebView *)webView createWebViewWithConfiguration:(WKWebViewConfiguration *)configuration forNavigationAction:(WKNavigationAction *)navigationAction windowFeatures:(WKWindowFeatures *)windowFeatures{

if (!navigationAction.targetFrame) {

[webView loadRequest:navigationAction.request];

}

return nil;

}

复制代码

打开其他应用

除了上述加载新页面的2种方式,还有一种从Html页面跳转到其他应用的情况。

比如说发邮件,发信息,打电话

发送邮件

给10086,10010发信息

10086打电话

复制代码

这种情况我们的需要在WKWebView的WKNavigationDelegate代理方法中处理应用跳转。

// Decides whether to allow or cancel a navigation.

- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler {

NSURL *url = navigationAction.request.URL;

if ([[UIApplication sharedApplication] canOpenURL:url]) {

[[UIApplication sharedApplication] openURL:url options:@{UIApplicationOpenURLOptionUniversalLinksOnly: @(NO)} completionHandler:^(BOOL success) {

// 成功调起三方App之后

NSLog(@"success:%@", @(success));

}];

decisionHandler(WKNavigationActionPolicyCancel);

} else {

// was called more than once'

decisionHandler(WKNavigationActionPolicyCancel);

}

}

复制代码

综上,我们在使用WKWebView加载新页面的时候可能用到如下代码

// Decides whether to allow or cancel a navigation.

- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler {

NSURL *url = navigationAction.request.URL;

if ([url.absoluteString hasPrefix:@"http"]) {

// The target frame, or nil if this is a new window navigation.

if (!navigationAction.targetFrame) {

[webView loadRequest:navigationAction.request];

}

decisionHandler(WKNavigationActionPolicyAllow);

} else if ([url.absoluteString hasPrefix:@"file://"]) {

// 加载本地文件

if (!navigationAction.targetFrame) {

[webView loadRequest:navigationAction.request];

}

decisionHandler(WKNavigationActionPolicyAllow);

} else {

if ([[UIApplication sharedApplication] canOpenURL:url]) {

[[UIApplication sharedApplication] openURL:url options:@{UIApplicationOpenURLOptionUniversalLinksOnly: @(NO)} completionHandler:^(BOOL success) {

// 成功调起三方App之后

NSLog(@"success:%@", @(success));

}];

decisionHandler(WKNavigationActionPolicyCancel);

} else {

// was called more than once'

decisionHandler(WKNavigationActionPolicyCancel);

}

}

}

复制代码

四、WKWebView显示JS弹框

笔者了解的弹框的方式有如下四种。笔者把下边下边的弹框分为2类,一类是使用js弹框,另一类是自定义的Toast。

自定义Toast

//自定义弹框

function Toast(msg,duration){

duration=isNaN(duration)?3000:duration;

var m = document.createElement('div');

m.innerHTML = msg;

m.style.cssText="width: 60%;min-width: 150px;opacity: 0.7;height: 200px;color: rgb(255, 255, 255);line-height: 100px;text-align: center;border-radius: 5px;position: fixed;top: 40%;left: 20%;z-index: 999999;background: rgb(0, 0, 0);font-size:48px;";

document.body.appendChild(m);

setTimeout(function() {

var d = 0.5;

m.style.webkitTransition = '-webkit-transform ' + d + 's ease-in, opacity ' + d + 's ease-in';

m.style.opacity = '0';

setTimeout(function() { document.body.removeChild(m) }, d * 1000);

}, duration);

}

复制代码

像自定义的Toast弹框,WKWebView可以正常显示,不需要我们处理。

js弹框

function alertFunction(){

alert("你好,我是一个警告框!");

}

function confirmFunction(){

window.confirm("confim 弹框");

}

function promptFunction(){

window.prompt("prompt 弹框");

}

复制代码

像js弹框,WKWebView无法显示js弹框。我们需要利用js和OC的交互在WKWebView的WKNavigationDelegate的方法中分别做如下处理。

//! Alert弹框

- (void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(void))completionHandler {

UIAlertController * alertController = [UIAlertController alertControllerWithTitle:@"提示" message:message ? : @"" preferredStyle:UIAlertControllerStyleAlert];

UIAlertAction * action = [UIAlertAction actionWithTitle:@"确认" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {

completionHandler();

}];

[alertController addAction:action];

[self presentViewController:alertController animated:YES completion:nil];

}

//! Confirm弹框

- (void)webView:(WKWebView *)webView runJavaScriptConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(BOOL))completionHandler {

UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"提示" message:message ?: @"" preferredStyle:UIAlertControllerStyleAlert];

UIAlertAction *confirmAction = [UIAlertAction actionWithTitle:@"确认" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {

completionHandler(YES);

}];

UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {

completionHandler(NO);

}];

[alertController addAction:confirmAction];

[alertController addAction:cancelAction];

[self presentViewController:alertController animated:YES completion:nil];

}

//! prompt弹框

- (void)webView:(WKWebView *)webView runJavaScriptTextInputPanelWithPrompt:(NSString *)prompt defaultText:(NSString *)defaultText initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(NSString * _Nullable))completionHandler {

UIAlertController * alertController = [UIAlertController alertControllerWithTitle:prompt message:@"" preferredStyle:UIAlertControllerStyleAlert];

[alertController addTextFieldWithConfigurationHandler:^(UITextField * _Nonnull textField) {

textField.text = defaultText;

}];

UIAlertAction * action = [UIAlertAction actionWithTitle:@"完成" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {

completionHandler(alertController.textFields[0].text ? : @"");

}];

[alertController addAction:action];

[self presentViewController:alertController animated:YES completion:nil];

}

复制代码

Demo

参考学习网址

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值