// // YMGoddessCertifiedProtocolView.m // MSYOUPAI // // Created by YoMi on 2024/3/2. // Copyright © 2024 MS. All rights reserved. // #import "YMGoddessCertifiedProtocolView.h" #import "YMGoddessCertifiedProtocolViewModel.h" @interface YMGoddessCertifiedProtocolView() /// 女神认证协议VM @property (nonatomic, strong) YMGoddessCertifiedProtocolViewModel *viewModel; /// 浏览器配置 @property (nonatomic, strong) WKWebViewConfiguration *webConfig; /// 网页文章浏览器 @property (nonatomic, strong) WKWebView *webArticleView; /// 进度条 @property (nonatomic, strong) UIProgressView *progressView; /// 当前Url @property (nonatomic, strong) NSURL *currentUrl; @end @implementation YMGoddessCertifiedProtocolView - (void)ym_setupViews{ [self addSubview:self.progressView]; [self addSubview:self.webArticleView]; } - (void)updateConstraints{ [self.progressView mas_makeConstraints:^(MASConstraintMaker *make) { make.top.equalTo(self); make.left.equalTo(self); make.right.equalTo(self); make.height.mas_equalTo(adapt(2)); }]; [self.webArticleView mas_makeConstraints:^(MASConstraintMaker *make) { make.top.equalTo(self.progressView.mas_bottom); make.left.equalTo(self); make.right.equalTo(self); make.bottom.equalTo(self); }]; [super updateConstraints]; } - (void)ym_bindViewModel:(YMGoddessCertifiedProtocolViewModel*)viewModel{ if (!viewModel) { return; } _viewModel = viewModel; @weakify(self) [[[[RACObserve(self.viewModel, webArticleUrl) distinctUntilChanged] deliverOnMainThread] takeUntil:self.rac_willDeallocSignal] subscribeNext:^(NSString * webArticleUrl) { @strongify(self) [self web_loadURLString:webArticleUrl]; }]; [[self.viewModel.refreshUISubject takeUntil:self.rac_willDeallocSignal] subscribeNext:^(id result) { @strongify(self) [self.webArticleView reload]; }]; self.webArticleView.ba_web_didStartBlock = ^(WKWebView *webView, WKNavigation *navigation) { @strongify(self) NSLog(@"开始加载网页"); }; self.webArticleView.ba_web_didFinishBlock = ^(WKWebView *webView, WKNavigation *navigation) { @strongify(self) NSLog(@"加载网页结束"); // WKWebview 禁止长按(超链接、图片、文本...)弹出效果 [webView ba_web_stringByEvaluateJavaScript:@"document.documentElement.style.webkitTouchCallout='none'" completionHandler:nil]; [webView ba_web_stringByEvaluateJavaScript:@"document.body.offsetHeight" completionHandler:^(id _Nullable result, NSError * _Nullable error) { [self.webArticleView mas_updateConstraints:^(MASConstraintMaker *make) { make.height.mas_equalTo([result doubleValue]); }]; }]; }; self.webArticleView.ba_web_isLoadingBlock = ^(BOOL isLoading, CGFloat progress) { @strongify(self) [self web_progressShow]; self.progressView.progress = progress; if (self.progressView.progress == 1.0f){ [self web_progressHidden]; } }; self.webArticleView.ba_web_getCurrentUrlBlock = ^(NSURL * _Nonnull currentUrl) { @strongify(self) self.currentUrl = currentUrl; }; } //iOS9.0以上异常终止时调用 - (void)webViewWebContentProcessDidTerminate:(WKWebView *)webView{ [webView reload]; } - (void)web_progressShow{ // 开始加载网页时展示出progressView self.progressView.hidden = NO; // 开始加载网页的时候将progressView的Height恢复为1.5倍 self.progressView.transform = CGAffineTransformMakeScale(1.0f, 1.5f); // 防止progressView被网页挡住 [self bringSubviewToFront:self.progressView]; } - (void)web_progressHidden{ /* *添加一个简单的动画,将progressView的Height变为1.4倍,在开始加载网页的代理中会恢复为1.5倍 *动画时长0.25s,延时0.3s后开始动画 *动画结束后将progressView隐藏 */ [UIView animateWithDuration:0.25f delay:0.3f options:UIViewAnimationOptionCurveEaseOut animations:^{ self.progressView.transform = CGAffineTransformMakeScale(1.0f, 1.4f); } completion:^(BOOL finished) { self.progressView.hidden = YES; }]; } /** * 加载一个 webview * * @param request 请求的 NSURL URLRequest */ - (void)web_loadRequest:(NSURLRequest *)request{ [self.webArticleView ba_web_loadRequest:request]; } /** * 加载一个 webview * * @param URL 请求的 URL */ - (void)web_loadURL:(NSURL *)URL{ [self.webArticleView ba_web_loadURL:URL]; } /** * 加载一个 webview * * @param URLString 请求的 URLString */ - (void)web_loadURLString:(NSString *)URLString{ [self.webArticleView ba_web_loadURLString:URLString]; } /** * 加载本地网页 * * @param htmlName 请求的本地 HTML 文件名 */ - (void)web_loadHTMLFileName:(NSString *)htmlName{ [self.webArticleView ba_web_loadHTMLFileName:htmlName]; } /** * 加载本地 htmlString * * @param htmlString 请求的本地 htmlString */ - (void)web_loadHTMLString:(NSString *)htmlString{ [self.webArticleView ba_web_loadHTMLString:htmlString]; } /** * 加载 js 字符串,例如:高度自适应获取代码: // webView 高度自适应 [self web_stringByEvaluateJavaScript:@"document.body.offsetHeight" completionHandler:^(id _Nullable result, NSError * _Nullable error) { // 获取页面高度,并重置 webview 的 frame self.ba_web_currentHeight = [result doubleValue]; CGRect frame = webView.frame; frame.size.height = self.ba_web_currentHeight; webView.frame = frame; }]; * * @param javaScriptString js 字符串 */ - (void)web_stringByEvaluateJavaScript:(NSString *)javaScriptString completionHandler:(void (^ _Nullable)(_Nullable id, NSError * _Nullable error))completionHandler{ [self.webArticleView ba_web_stringByEvaluateJavaScript:javaScriptString completionHandler:completionHandler]; } - (void)setWeb_progressTintColor:(UIColor *)web_progressTintColor{ _web_progressTintColor = web_progressTintColor; self.progressView.progressTintColor = web_progressTintColor; } - (void)setWeb_progressTrackTintColor:(UIColor *)web_progressTrackTintColor{ _web_progressTrackTintColor = web_progressTrackTintColor; self.progressView.trackTintColor = web_progressTrackTintColor; } - (UIProgressView *)progressView { if (!_progressView){ _progressView = [[UIProgressView alloc] initWithFrame:CGRectZero]; _progressView.tintColor = BAKit_Color_Green_pod; _progressView.trackTintColor = BAKit_Color_Gray_8_pod; _progressView.transform = CGAffineTransformMakeScale(1.0f, 1.5f); } return _progressView; } - (WKWebViewConfiguration *)webConfig{ if (!_webConfig) { // 创建并配置WKWebView的相关参数 // 1.WKWebViewConfiguration:是WKWebView初始化时的配置类,里面存放着初始化WK的一系列属性; // 2.WKUserContentController:为JS提供了一个发送消息的通道并且可以向页面注入JS的类,WKUserContentController对象可以添加多个scriptMessageHandler; // 3.addScriptMessageHandler:name:有两个参数,第一个参数是userContentController的代理对象,第二个参数是JS里发送postMessage的对象。添加一个脚本消息的处理器,同时需要在JS中添加,window.webkit.messageHandlers..postMessage()才能起作用。 _webConfig = [[WKWebViewConfiguration alloc] init]; _webConfig.allowsInlineMediaPlayback = YES; WKUserContentController *userContentController = [[WKUserContentController alloc] init]; _webConfig.userContentController = userContentController; // 初始化偏好设置属性:preferences _webConfig.preferences = [WKPreferences new]; // The minimum font size in points default is 0; _webConfig.preferences.minimumFontSize = 15; // 是否支持 JavaScript _webConfig.preferences.javaScriptEnabled = YES; // 不通过用户交互,是否可以打开窗口 _webConfig.preferences.javaScriptCanOpenWindowsAutomatically = NO; } return _webConfig; } - (WKWebView *)webArticleView{ if (!_webArticleView) { _webArticleView = [[WKWebView alloc] initWithFrame:CGRectZero configuration:self.webConfig]; [_webArticleView ba_web_initWithDelegate:self.webArticleView.navigationDelegate uIDelegate:self.webArticleView.UIDelegate]; _webArticleView.ba_web_isAutoHeight = NO; _webArticleView.multipleTouchEnabled = YES; _webArticleView.autoresizesSubviews = YES; _webArticleView.opaque = NO; _webArticleView.backgroundColor = HexColorFromRGB(0xFFFFFF); _webArticleView.scrollView.showsVerticalScrollIndicator = NO; } return _webArticleView; } @end