WKWebView的使用
来源:互联网 发布:源代码加密软件 编辑:程序博客网 时间:2024/06/07 11:37
iOS8.0之后苹果推出了新框架Webkit,提供了WKWebView的组件,用来替换UIWebView。之前UIWebView 加载速度慢,占用内存大,如果加载的网页比较多,占用内存比较大可能还会导致项目crash。WKWebView在性能上有了很大的优化,占用内存小,允许JavaScript的Nitro库加载并使用,支持了更多的HTML5特性。
WKWebView的使用
自定义一个WKWebVC
声明两个属性
@property (nonatomic,strong) WKWebView *webView;@property (nonatomic,copy) NSString *urlStr;
定义几个静态字符串 用来初始化注册js方法
static NSString * const JSHandlerNameShare = @"share";static NSString * const JSHandlerNameHideNavBar = @"hideNavBar";static NSString * const JSHandlerNameShowNavBar = @"showNavBar";static NSString * const JSHandlerNameSetNavBarAlpha = @"setNavBarAlpha";
初始化WKWebView
- (WKWebView *)webView { if (!_webView) { WKWebViewConfiguration *config = [[WKWebViewConfiguration alloc] init]; //允许html内联播放 config.allowsInlineMediaPlayback = YES; _webView = [[WKWebView alloc] initWithFrame:self.view.bounds configuration:config]; _webView.backgroundColor = [UIColor whiteColor]; _webView.navigationDelegate = self; _webView.UIDelegate = self; _webView.scrollView.delegate = self; //注册js方法 [_webView.configuration.userContentController addScriptMessageHandler:self name:JSHandlerNameShare]; [_webView.configuration.userContentController addScriptMessageHandler:self name:JSHandlerNameHideNavBar]; [_webView.configuration.userContentController addScriptMessageHandler:self name:JSHandlerNameSetNavBarAlpha]; } return _webView;}
加载webView
- (void)setUrlStr:(NSString *)urlStr{ _urlStr = urlStr; NSURL *url = [NSURL URLWithString:urlStr]; NSURLRequest *request = [[NSURLRequest alloc] initWithURL:url cachePolicy:0 timeoutInterval:10.0]; [self.webView loadRequest:request]; [self.view addSubview:self.webView];}
遵守相应的代理协议并实现相应的代理方法
WKNavigationDelegate 代理方法如下:
- (void)webView:(WKWebView *)webView didStartProvisionalNavigation:(WKNavigation *)navigation{ //在此可以显示加载动画 NSLog(@"页面开始加载时调用");}- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation{ //停止加载动画 NSLog(@"页面加载完毕");}- (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(WKNavigation *)navigation withError:(NSError *)error{ //页面加载失败,添加失败页面,或者是添加重新加载按钮 //重新加载需要重新赋值请求链接 重新loadRequest NSLog(@"页面加载失败");}- (void)webView:(WKWebView *)webView didCommitNavigation:(WKNavigation *)navigation{ //内容返回后,加载动画停止 NSLog(@"当内容返回的时候调用");}
跳转前会调用以下这个方法,在跳转前可以进行判断跳转的链接,根据跟前端开发协商好的协议头和主机位判断是属于那种跳转,在这个方法中可以进行相应的操作。
- (void)webView:(WKWebView )webView decidePolicyForNavigationAction:(WKNavigationAction )navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler;
声明一个通知 用于监听是属于那种跳转
extern NSString * const WKJumpNotification;
为该属性赋值
NSString * const WKJumpNotification = @"WKJumpNotification";
在viewDidLoad 中添加通知
- (void)viewDidLoad { [super viewDidLoad]; self.view.backgroundColor = [UIColor whiteColor]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(jumpAction:) name:WKJumpNotification object:nil];}
在请求链接跳转前进行如下监听
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler{ //可以在此进行判断是属于那种跳转类型 //获取跳转链接 NSURL *url = navigationAction.request.URL; //根据约定好的协议头进行判断 if ([url.scheme isEqualToString:@"saga"]) { [[NSNotificationCenter defaultCenter] postNotificationName:WKJumpNotification object:nil userInfo:@{@"url":url}]; //不允许跳转 decisionHandler(WKNavigationActionPolicyCancel); } else { //允许页面跳转 decisionHandler(WKNavigationActionPolicyAllow); } NSLog(@"跳转前调用,决定是否跳转");}
定义一个枚举判断是属于那种跳转
typedef enum { WKWebVCRequestTypeCustomerService = 1001,//客服列表 WKWebVCRequestTypeProductDetail = 1002,//商品详情 WKWebVCRequestTypeOrderDetail = 1003//订单详情}WKWebVCRequestType;
通知方法的执行
- (void)jumpAction:(NSNotification *)notification{ NSDictionary *dict = notification.userInfo; id url = dict[@"url"]; if (![url isKindOfClass:[NSURL class]]) { NSLog(@"参数不是请求URL"); return; } NSURL *requestUrl = url; //根据主机位判断是属于那种跳转类型 这主机位事先跟web前端约定好 WKWebVCRequestType type = requestUrl.host.intValue; switch (type) { case WKWebVCRequestTypeCustomerService: NSLog(@"跳转到客服列表"); break; case WKWebVCRequestTypeProductDetail: NSLog(@"跳转到商品详情"); break; case WKWebVCRequestTypeOrderDetail: NSLog(@"跳转到订单详情"); break; default: break; }}
WKUIDelegate 的相应代理方法的使用 处理web界面的三种提示框(警告框、确认框、输入框)
//弹出提示框- (void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(void))completionHandler { UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"温馨提示" message:message delegate:self cancelButtonTitle:@"确定" otherButtonTitles: nil]; [alertView show]; completionHandler();}//弹出确认框- (void)webView:(WKWebView *)webView runJavaScriptConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(BOOL))completionHandler { UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"确认框" message:message delegate:self cancelButtonTitle:@"取消" otherButtonTitles: @"确定",nil]; [alertView show];}//弹出输入框- (void)webView:(WKWebView *)webView runJavaScriptTextInputPanelWithPrompt:(NSString *)prompt defaultText:(NSString *)defaultText initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(NSString * _Nullable))completionHandler { UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:prompt message:nil delegate:self cancelButtonTitle:@"取消" otherButtonTitles: @"确定",nil]; [alertView show];}
WKScriptMessageHandler 协议的使用,它能让网页通过JS把消息发送给OC
//网页通过JS把消息发送给OC- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message{ //判断网页是进行那种操作 if ([message.name isEqualToString:JSHandlerNameShare]) { //分享 if ([message.body isKindOfClass:[NSDictionary class]]) { //分享字典模型数据 NSDictionary *dict = message.body; } NSLog(@"在此可以弹出分享面板"); } else if ([message.name isEqualToString:JSHandlerNameHideNavBar]) { NSLog(@"隐藏导航栏"); } else if ([message.name isEqualToString:JSHandlerNameShowNavBar]) { NSLog(@"显示导航栏"); } else if ([message.name isEqualToString:JSHandlerNameSetNavBarAlpha]) { if ([message.body isKindOfClass:[NSDictionary class]]) { //根据模型字典中的数据设置导航栏的透明度 NSDictionary *dict = message.body; } NSLog(@"设置导航栏的透明度"); } else { NSLog(@"没有注册此操作"); }}
在开发中使用WKWebView遇到一些问题
- (void)dealloc;中发现self没有被释放,原因是注册的js事件没有移除
为了释放self 我在viewWillDisAppear里进行了如下操作
- (void)viewWillDisappear:(BOOL)animated{ //移除之前注册的js回调,不然会导致webView无法正常释放。 [self.webView.configuration.userContentController removeScriptMessageHandlerForName:JSHandlerNameShare]; [self.webView.configuration.userContentController removeScriptMessageHandlerForName:JSHandlerNameHideNavBar]; [self.webView.configuration.userContentController removeScriptMessageHandlerForName:JSHandlerNameShowNavBar]; [self.webView.configuration.userContentController removeScriptMessageHandlerForName:JSHandlerNameSetNavBarAlpha];}
由于webView指定了UIScrollViewDelegate,所以要在dealloc中将webView的滚动代理赋值为nil,否则会导致crash
- (void)dealloc{ //需要将滚动的代理赋值为nil否则会导致crash _webView.scrollView.delegate = nil; [[NSNotificationCenter defaultCenter] removeObserver:self];}
这是个人使用WKWebView的总结
- WKWebView的使用心得
- WKWebView的使用
- WKWebView 的使用简介
- WKWebView 的使用简介
- 简单的使用WKWebView
- WKWebView 的使用简介
- WKWebView的详细使用
- WKWebView的使用详解
- WKWebView的使用
- WKWebView 的使用简介
- iOS WKWebView的使用
- WKWebView 的使用简介
- WKWebView的使用
- WKWebView的使用
- WKWebView的使用
- WKWebView的简单使用
- WKWebView的使用
- WKWebView 的使用
- Bmp格式说明
- 无线网卡掉线解决办法
- 正则表达式 \\\\
- Assign Cookies
- bzoj 1040感悟
- WKWebView的使用
- vsftpd服务的配置(本地用户)
- Find Largest Value in Each Tree Row
- 反射机制
- 输入命令导出oracle
- python正则表达式学习
- jQuery中attr()方法和prop()方法获取input的checked属性的区别
- Android Rect类的构造函数参数说明
- 电商系列---mysql高并发超库存卖问题