Commit 2ef7bbf0a21e70c280611f9493c06984a26849cd

Authored by zhangxiaowen
1 parent 1db03f45

no message

CNLiveCustomControl.podspec
@@ -48,6 +48,11 @@ TODO: 网家家-自定义控件. @@ -48,6 +48,11 @@ TODO: 网家家-自定义控件.
48 ss.dependency 'CNLiveCategory' 48 ss.dependency 'CNLiveCategory'
49 end 49 end
50 50
  51 + s.subspec 'WebView' do |ss|
  52 + ss.source_files = 'CNLiveCustomControl/Classes/WebView/*'
  53 + ss.dependency 'CNLiveTripartiteManagement/QMUIKit'
  54 + end
  55 +
51 # s.resource_bundles = { 56 # s.resource_bundles = {
52 # 'CNLiveCustomControl' => ['CNLiveCustomControl/Assets/*.png'] 57 # 'CNLiveCustomControl' => ['CNLiveCustomControl/Assets/*.png']
53 # } 58 # }
CNLiveCustomControl/Classes/CNLiveCustomControl.h
@@ -15,5 +15,7 @@ @@ -15,5 +15,7 @@
15 //NavigationBar 15 //NavigationBar
16 #import "CNLiveNavigationBar.h" 16 #import "CNLiveNavigationBar.h"
17 17
  18 +//WebView
  19 +#import "CNLiveWebView.h"
18 20
19 #endif /* CNLiveCustomControl_h */ 21 #endif /* CNLiveCustomControl_h */
CNLiveCustomControl/Classes/WebView/CNLiveWebView.h 0 → 100755
  1 +//
  2 +// CNLiveWebView.h
  3 +// CNLiveBaseClass
  4 +//
  5 +// Created by CNLive-zxw on 2019/9/12.
  6 +// Copyright © 2019 153993236@qq.com. All rights reserved.
  7 +//
  8 +
  9 +/*
  10 + * 自定义WebView
  11 + */
  12 +
  13 +#import <UIKit/UIKit.h>
  14 +#import <WebKit/WebKit.h>
  15 +
  16 +NS_ASSUME_NONNULL_BEGIN
  17 +@class CNLiveWebView;
  18 +
  19 +@protocol CNLiveWebViewDelegate <NSObject>
  20 +@optional
  21 +/** 页面开始加载时调用 */
  22 +- (void)webViewDidStartLoad:(CNLiveWebView *)webView;
  23 +/** 内容开始返回时调用 */
  24 +- (void)webView:(CNLiveWebView *)webView didCommitWithURL:(NSURL *)url;
  25 +/** 页面加载失败时调用 */
  26 +- (void)webView:(CNLiveWebView *)webView didFinishLoadWithURL:(NSURL *)url;
  27 +/** 页面加载完成之后调用 */
  28 +- (void)webView:(CNLiveWebView *)webView didFailLoadWithError:(NSError *)error;
  29 +
  30 +@end
  31 +
  32 +@interface CNLiveWebView : UIView
  33 +@property (nonatomic, strong) WKWebView *wkWebView;
  34 +@property (nonatomic, strong) UIProgressView *progressView;
  35 +
  36 +/** CNLiveWebViewDelegate */
  37 +@property (nonatomic, weak) id<CNLiveWebViewDelegate> delegate;
  38 +/** 进度条颜色(默认蓝色) */
  39 +@property (nonatomic, strong) UIColor *progressViewColor;
  40 +/** 导航栏标题 */
  41 +@property (nonatomic, copy) NSString *title;
  42 +
  43 +@property (nonatomic, readonly) BOOL canGoBack;
  44 +/** 向后 */
  45 +- (nullable WKNavigation *)goBack;
  46 +
  47 +@property (nonatomic, readonly) BOOL canGoForward;
  48 +/** 向前 */
  49 +- (nullable WKNavigation *)goForward;
  50 +/** 刷新数据 */
  51 +- (void)reloadData;
  52 +
  53 +/** 类方法创建 XWWebView */
  54 ++ (instancetype)webViewWithFrame:(CGRect)frame;
  55 +/** 加载 web */
  56 +- (void)loadRequest:(NSURLRequest *)request;
  57 +/** 加载 HTML */
  58 +- (void)loadHTMLString:(NSString *)HTMLString;
  59 +
  60 +@end
  61 +NS_ASSUME_NONNULL_END
CNLiveCustomControl/Classes/WebView/CNLiveWebView.m 0 → 100755
  1 +//
  2 +// CNLiveWebView.h
  3 +// CNLiveBaseClass
  4 +//
  5 +// Created by CNLive-zxw on 2019/9/12.
  6 +// Copyright © 2019 153993236@qq.com. All rights reserved.
  7 +//
  8 +
  9 +#import "CNLiveWebView.h"
  10 +#import "QMUIKit.h"
  11 +
  12 +@interface CNLiveWebView () <WKNavigationDelegate, WKUIDelegate>
  13 +
  14 +@end
  15 +
  16 +@implementation CNLiveWebView
  17 +static CGFloat const progressViewHeight = 1;
  18 +
  19 +#pragma mark - 初始化
  20 +- (instancetype)initWithFrame:(CGRect)frame {
  21 + if (self = [super initWithFrame:frame]) {
  22 + if (@available(iOS 11, *)) {
  23 + self.wkWebView.scrollView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentAutomatic;
  24 + }
  25 + [self addSubview:self.progressView];
  26 + [self addSubview:self.wkWebView];
  27 + }
  28 + return self;
  29 +}
  30 +
  31 ++ (instancetype)webViewWithFrame:(CGRect)frame {
  32 + return [[self alloc] initWithFrame:frame];
  33 +}
  34 +
  35 +// dealloc
  36 +- (void)dealloc {
  37 + [_wkWebView stopLoading];
  38 + [_wkWebView removeObserver:self forKeyPath:NSStringFromSelector(@selector(estimatedProgress))];
  39 + _wkWebView.navigationDelegate = nil;
  40 + _wkWebView = nil;
  41 +}
  42 +
  43 +#pragma mark - Setter方法
  44 +- (void)setProgressViewColor:(UIColor *)progressViewColor {
  45 + _progressViewColor = progressViewColor;
  46 + if (progressViewColor) {
  47 + _progressView.tintColor = progressViewColor;
  48 + }
  49 +}
  50 +
  51 +#pragma mark - Getter方法
  52 +- (BOOL)canGoBack{
  53 + return self.wkWebView.goBack;
  54 +}
  55 +
  56 +- (BOOL)canGoForward{
  57 + return self.wkWebView.canGoForward;
  58 +}
  59 +
  60 +#pragma mark - 工具方法
  61 +// 向后
  62 +- (nullable WKNavigation *)goBack{
  63 + return [self.wkWebView goBack];
  64 +}
  65 +// 向前
  66 +- (nullable WKNavigation *)goForward{
  67 + return [self.wkWebView goForward];
  68 +}
  69 +// 刷新数据
  70 +- (void)reloadData {
  71 + [self.wkWebView reload];
  72 +}
  73 +// 加载 web
  74 +- (void)loadRequest:(NSURLRequest *)request {
  75 + [self.wkWebView loadRequest:request];
  76 +}
  77 +// 加载 HTML
  78 +- (void)loadHTMLString:(NSString *)HTMLString {
  79 + [self.wkWebView loadHTMLString:HTMLString baseURL:nil];
  80 +}
  81 +
  82 +#pragma mark - KVO
  83 +- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context {
  84 + if ([keyPath isEqualToString:NSStringFromSelector(@selector(estimatedProgress))] && object == self.wkWebView) {
  85 + self.progressView.alpha = 1.0;
  86 + BOOL animated = self.wkWebView.estimatedProgress > self.progressView.progress;
  87 + [self.progressView setProgress:self.wkWebView.estimatedProgress animated:animated];
  88 + if(self.wkWebView.estimatedProgress >= 0.97) {
  89 + [UIView animateWithDuration:0.1 delay:0.3 options:UIViewAnimationOptionCurveEaseOut animations:^{
  90 + self.progressView.alpha = 0.0;
  91 + } completion:^(BOOL finished) {
  92 + [self.progressView setProgress:0.0 animated:NO];
  93 + }];
  94 + }
  95 + } else {
  96 + [super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
  97 + }
  98 +}
  99 +
  100 +#pragma mark - WKNavigationDelegate
  101 +// 在发送请求之前,决定是否跳转
  102 +- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler{
  103 + //允许跳转
  104 + decisionHandler(WKNavigationActionPolicyAllow);
  105 +}
  106 +// 在收到响应后,决定是否跳转
  107 +- (void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler{
  108 + //允许跳转
  109 + decisionHandler(WKNavigationResponsePolicyAllow);
  110 + //不允许跳转
  111 + //decisionHandler(WKNavigationResponsePolicyCancel);
  112 +}
  113 +// 页面开始加载时调用
  114 +- (void)webView:(WKWebView *)webView didStartProvisionalNavigation:(WKNavigation *)navigation {
  115 + if (self.delegate && [self.delegate respondsToSelector:@selector(webViewDidStartLoad:)]) {
  116 + [self.delegate webViewDidStartLoad:self];
  117 + }
  118 +}
  119 +// 当内容开始返回时调用
  120 +- (void)webView:(WKWebView *)webView didCommitNavigation:(WKNavigation *)navigation {
  121 + if (self.delegate && [self.delegate respondsToSelector:@selector(webView:didCommitWithURL:)]) {
  122 + [self.delegate webView:self didCommitWithURL:self.wkWebView.URL];
  123 + }
  124 +}
  125 +// 页面加载完成之后调用
  126 +- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation {
  127 + if(!self.title){
  128 + self.title = self.wkWebView.title;
  129 + }
  130 + if (self.delegate && [self.delegate respondsToSelector:@selector(webView:didFinishLoadWithURL:)]) {
  131 + [self.delegate webView:self didFinishLoadWithURL:self.wkWebView.URL];
  132 + }
  133 + self.progressView.alpha = 0.0;
  134 +}
  135 +// 页面加载失败时调用
  136 +- (void)webView:(WKWebView *)webView didFailNavigation:(WKNavigation *)navigation withError:(NSError *)error {
  137 + if (self.delegate && [self.delegate respondsToSelector:@selector(webView:didFailLoadWithError:)]) {
  138 + [self.delegate webView:self didFailLoadWithError:error];
  139 + }
  140 + self.progressView.alpha = 0.0;
  141 +}
  142 +// 页面加载失败时调用
  143 +- (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(null_unspecified WKNavigation *)navigation withError:(nonnull NSError *)error{
  144 + if (self.delegate && [self.delegate respondsToSelector:@selector(webView:didFailLoadWithError:)]) {
  145 + [self.delegate webView:self didFailLoadWithError:error];
  146 + }
  147 + self.progressView.alpha = 0.0;
  148 +}
  149 +// 接收到服务器跳转请求之后调用(重定向)
  150 +- (void)webView:(WKWebView *)webView didReceiveServerRedirectForProvisionalNavigation:(WKNavigation *)navigation{
  151 +
  152 +}
  153 +
  154 +#pragma mark - 懒加载
  155 +- (WKWebView *)wkWebView {
  156 + if (!_wkWebView) {
  157 + NSMutableString *javascript = [NSMutableString string];
  158 + [javascript appendString:@"document.documentElement.style.webkitTouchCallout='none';"];//禁止长按
  159 + [javascript appendString:@"document.documentElement.style.webkitUserSelect='none';"];//禁止选择
  160 + WKUserScript *noneSelectScript = [[WKUserScript alloc] initWithSource:javascript injectionTime:WKUserScriptInjectionTimeAtDocumentEnd forMainFrameOnly:YES];
  161 + WKWebViewConfiguration *configuration = [[WKWebViewConfiguration alloc] init];
  162 + configuration.allowsInlineMediaPlayback = YES;
  163 + WKPreferences *preferences = [WKPreferences new];
  164 + //很重要,如果没有设置这个则不会回调createWebViewWithConfiguration方法,也不会回应window.open()方法
  165 + preferences.javaScriptCanOpenWindowsAutomatically = YES;
  166 + configuration.preferences = preferences;
  167 + _wkWebView = [[WKWebView alloc] initWithFrame:CGRectMake(0, progressViewHeight, self.frame.size.width, self.frame.size.height-progressViewHeight) configuration:configuration];
  168 + [_wkWebView.configuration.userContentController addUserScript:noneSelectScript];
  169 + _wkWebView.allowsLinkPreview = NO;
  170 + _wkWebView.UIDelegate = self;
  171 + _wkWebView.navigationDelegate = self;
  172 + [_wkWebView addObserver:self forKeyPath:NSStringFromSelector(@selector(estimatedProgress)) options:0 context:nil];
  173 + }
  174 + return _wkWebView;
  175 +}
  176 +
  177 +- (UIProgressView *)progressView {
  178 + if (!_progressView) {
  179 + _progressView = [[UIProgressView alloc] initWithProgressViewStyle:UIProgressViewStyleDefault];
  180 + _progressView.trackTintColor = [UIColor clearColor];
  181 + // 高度默认有导航栏且有穿透效果
  182 + _progressView.frame = CGRectMake(0, 0, self.frame.size.width, progressViewHeight);
  183 + // 设置进度条颜色
  184 + _progressView.tintColor = [UIColor colorWithRed:19/255.0 green:204/255.0 blue:12/255.0 alpha:1.0];
  185 + _progressView.progressTintColor = [UIColor colorWithRed:19/255.0 green:204/255.0 blue:12/255.0 alpha:1.0];
  186 + }
  187 + return _progressView;
  188 +}
  189 +
  190 +@end