WKWebViewVC.m 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. //
  2. // WKWebViewVC.m
  3. // PoliceHome
  4. //
  5. // Created by 刘惠萍 on 2020/12/15.
  6. // Copyright © 2020 刘惠萍. All rights reserved.
  7. //
  8. #import "WKWebViewVC.h"
  9. #import <WebKit/WebKit.h>
  10. @interface WKWebViewVC ()<WKNavigationDelegate>
  11. @property (nonatomic, strong) WKWebView * webView;
  12. ///网页加载进度视图
  13. @property (nonatomic, strong) UIProgressView * progressView;
  14. /// WKWebView 内容的高度
  15. @property (nonatomic, assign) CGFloat webContentHeight;
  16. @property (nonatomic, strong) BaseNavView *navView;
  17. @end
  18. @implementation WKWebViewVC
  19. - (BaseNavView *)navView{
  20. if (!_navView) {
  21. _navView = [BaseNavView initNavBackTitle:UnPackStr(self.navStr) rightView:nil];
  22. WEAKSELF
  23. _navView.blockBack = ^{
  24. if (weakSelf.webView.canGoBack) {
  25. [weakSelf.webView goBack];
  26. }else{
  27. [GB_Nav popViewControllerAnimated:true];
  28. }
  29. };
  30. }
  31. return _navView;
  32. }
  33. #pragma mark - Override
  34. - (void)viewDidLoad {
  35. [super viewDidLoad];
  36. if (self.isNav) {
  37. [self.view addSubview:self.navView];
  38. }
  39. [self setupUI];
  40. [self addKVO];
  41. }
  42. - (void)viewWillDisappear:(BOOL)animated {
  43. [super viewWillDisappear:animated];
  44. [self.progressView removeFromSuperview];
  45. }
  46. - (void)dealloc {
  47. [self removeKVO];
  48. [NSURLProtocol registerClass:[NSURLProtocol class]];
  49. }
  50. #pragma mark - UI
  51. - (void)setupUI {
  52. self.view.backgroundColor = UIColor.whiteColor;
  53. //设置自定义Cookie在WKWebView初始化之前
  54. [self.view addSubview:self.webView];
  55. }
  56. #pragma mark - Getter
  57. - (WKWebView *)webView {
  58. if(_webView == nil){
  59. //创建网页配置
  60. WKWebViewConfiguration *config = [[WKWebViewConfiguration alloc] init];
  61. _webView = [[WKWebView alloc] initWithFrame:CGRectMake(0, self.isNav?NAVIGATIONBAR_HEIGHT:0, SCREEN_WIDTH, self.isNav?SCREEN_HEIGHT-NAVIGATIONBAR_HEIGHT:self.isHight?SCREEN_HEIGHT-NAVIGATIONBAR_HEIGHT-W(55)-W(84):SCREEN_HEIGHT) configuration:config];
  62. _webView.navigationDelegate = self;
  63. //以下代码适配文本大小
  64. NSString *jSString = @"var meta = document.createElement('meta'); meta.setAttribute('name', 'viewport'); meta.setAttribute('content', 'width=device-width'); document.getElementsByTagName('head')[0].appendChild(meta);";
  65. //用于进行JavaScript注入
  66. WKUserScript *wkUScript = [[WKUserScript alloc] initWithSource:jSString injectionTime:WKUserScriptInjectionTimeAtDocumentEnd forMainFrameOnly:YES];
  67. [config.userContentController addUserScript:wkUScript];
  68. _webView.allowsBackForwardNavigationGestures = YES;
  69. if (self.isH5) {
  70. NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:UnPackStr(self.htmlString)]];
  71. [_webView loadRequest:request];
  72. }else{
  73. [_webView loadHTMLString:UnPackStr(self.htmlString) baseURL:[NSURL fileURLWithPath:[[NSBundle mainBundle] bundlePath]]];
  74. }
  75. }
  76. return _webView;
  77. }
  78. - (UIProgressView *)progressView {
  79. if (!_progressView){
  80. _progressView = [[UIProgressView alloc] initWithFrame:CGRectMake(0, 0, SCREEN_WIDTH, 2)];
  81. _progressView.tintColor = [UIColor blueColor];
  82. _progressView.trackTintColor = [UIColor clearColor];
  83. }
  84. if (_progressView.superview == nil) {
  85. [self.navigationController.navigationBar addSubview:_progressView];
  86. }
  87. return _progressView;
  88. }
  89. #pragma mark - KVO
  90. ///添加键值对监听
  91. - (void)addKVO {
  92. //监听网页加载进度
  93. [self.webView addObserver:self
  94. forKeyPath:NSStringFromSelector(@selector(estimatedProgress))
  95. options:NSKeyValueObservingOptionNew
  96. context:nil];
  97. [self.webView addObserver:self
  98. forKeyPath:@"title"
  99. options:NSKeyValueObservingOptionNew
  100. context:nil];
  101. }
  102. ///移除监听
  103. - (void)removeKVO {
  104. //移除观察者
  105. [_webView removeObserver:self
  106. forKeyPath:NSStringFromSelector(@selector(estimatedProgress))];
  107. [_webView removeObserver:self
  108. forKeyPath:NSStringFromSelector(@selector(title))];
  109. }
  110. //kvo监听 必须实现此方法
  111. -(void)observeValueForKeyPath:(NSString *)keyPath
  112. ofObject:(id)object
  113. change:(NSDictionary<NSKeyValueChangeKey,id> *)change
  114. context:(void *)context{
  115. if ([keyPath isEqualToString:NSStringFromSelector(@selector(estimatedProgress))]
  116. && object == _webView) {
  117. NSLog(@"网页加载进度 = %f",_webView.estimatedProgress);
  118. self.progressView.progress = _webView.estimatedProgress;
  119. if (_webView.estimatedProgress >= 1.0f) {
  120. dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
  121. self.progressView.progress = 0;
  122. });
  123. }
  124. }else if([keyPath isEqualToString:@"title"]
  125. && object == _webView){
  126. self.navStr = _webView.title;
  127. // [_navView changeTitle:UnPackStr(self.navStr)];
  128. }
  129. }
  130. #pragma mark - Events Handle
  131. //返回上一步
  132. - (void)goBackAction:(id)sender{
  133. if (_webView.canGoBack) {
  134. [_webView goBack];
  135. }else{
  136. }
  137. }
  138. //前往下一步
  139. - (void)goForwardAction:(id)sender{
  140. [_webView goForward];
  141. }
  142. #pragma mark - WKNavigationDelegate
  143. // 根据WebView对于即将跳转的HTTP请求头信息和相关信息来决定是否跳转
  144. - (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler {
  145. //请求头信息
  146. NSDictionary *allHTTPHeaderFields = [navigationAction.request allHTTPHeaderFields];
  147. NSLog(@" UserAgent: %@",allHTTPHeaderFields[@"User-Agent"]);
  148. decisionHandler(WKNavigationActionPolicyAllow);
  149. }
  150. // 根据客户端受到的服务器响应头以及response相关信息来决定是否可以跳转
  151. - (void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler{
  152. if ([navigationResponse.response isKindOfClass:[NSHTTPURLResponse class]] && [navigationResponse.response.URL.absoluteString isEqualToString:self.htmlString]) {
  153. NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)navigationResponse.response;
  154. if (httpResponse.statusCode == 304) {
  155. //自上次请求后,文件还没有修改变化
  156. //可以加载本地缓存
  157. }else if (httpResponse.statusCode == 200){
  158. // [SLMethod userDefaultsSetObject:httpResponse.allHeaderFields[@"Last-Modified"] forKey:@"localLastModified"];
  159. NSLog(@" httpResponse:%@",httpResponse);
  160. }
  161. }
  162. //允许跳转
  163. decisionHandler(WKNavigationResponsePolicyAllow);
  164. }
  165. // 页面加载完成之后调用
  166. - (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation {
  167. }
  168. //进程被终止时调用
  169. - (void)webViewWebContentProcessDidTerminate:(WKWebView *)webView{
  170. //当 WKWebView 总体内存占用过大,页面即将白屏的时候,系统会调用此7u776回调函数,我们在该函数里执行[webView reload](这个时候 webView.URL 取值尚不为 nil)解决白屏问题。在一些高内存消耗的页面可能会频繁刷新当前页面,H5侧也要做相应的适配操作。
  171. [webView reload];
  172. }
  173. @end