// // PQBaseWebViewController.swift // PQSpeed // // Created by SanW on 2020/5/27. // Copyright © 2020 BytesFlow. All rights reserved. // import UIKit import WebKit public class PQBaseWebViewController: PQBaseViewController { var emptyData: PQEmptyModel? = { let emptyData = PQEmptyModel() emptyData.title = "网页加载失败,请重试~" emptyData.emptyImage = "pic_network" return emptyData }() lazy var webView: WKWebView = { let config: WKWebViewConfiguration = WKWebViewConfiguration() config.allowsInlineMediaPlayback = true let webView: WKWebView = WKWebView(frame: CGRect(x: 0, y: cDevice_iPhoneNavBarAndStatusBarHei, width: cScreenWidth, height: cScreenHeigth - cDevice_iPhoneNavBarAndStatusBarHei), configuration: config) webView.backgroundColor = UIColor.white if #available(iOS 11.0, *) { webView.scrollView.contentInsetAdjustmentBehavior = .never } else { automaticallyAdjustsScrollViewInsets = false } webView.navigationDelegate = self return webView }() lazy var progresslayer: CALayer = { let progresslayer = CALayer() progresslayer.frame = CGRect(x: 0, y: cDevice_iPhoneNavBarAndStatusBarHei, width: cScreenWidth * 0.1, height: 2) progresslayer.backgroundColor = UIColor.hexColor(hexadecimal: "#FF9500").cgColor return progresslayer }() @objc public var baseUrl: String? { didSet { if baseUrl != nil, baseUrl?.count ?? 0 > 0 { webView.load(URLRequest(url: NSURL(string: baseUrl ?? "")! as URL, cachePolicy: .reloadIgnoringCacheData)) // 添加属性监听 webView.addObserver(self, forKeyPath: "estimatedProgress", options: .new, context: nil) isAddObserve = true view.layer.addSublayer(progresslayer) } } } @objc var baseTitle: String? public var evaluateJavaScript: String? // 交互 var isAddObserve: Bool = false override open func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view. view.addSubview(webView) leftButton(image: "icon_blanc_back") navHeadImageView?.backgroundColor = UIColor.white } override public func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) if (UIApplication.shared.keyWindow?.viewWithTag(cProtocalViewTag)) != nil { (UIApplication.shared.keyWindow?.viewWithTag(cProtocalViewTag))?.isHidden = true } } override public func viewWillDisappear(_ animated: Bool) { super.viewWillDisappear(animated) if (UIApplication.shared.keyWindow?.viewWithTag(cProtocalViewTag)) != nil { (UIApplication.shared.keyWindow?.viewWithTag(cProtocalViewTag))?.isHidden = false } } deinit { if isAddObserve { webView.removeObserver(self, forKeyPath: "estimatedProgress") } } } extension PQBaseWebViewController: WKNavigationDelegate { func refreshClick() { if baseUrl != nil, baseUrl?.count ?? 0 > 0 { webView.load(URLRequest(url: NSURL(string: baseUrl ?? "")! as URL, cachePolicy: .useProtocolCachePolicy)) } } @objc func back() { if webView.canGoBack { webView.goBack() } else if navigationController != nil { navigationController?.popViewController(animated: true) } else { dismiss(animated: true, completion: nil) } } override public func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey: Any]?, context: UnsafeMutableRawPointer?) { if keyPath == "estimatedProgress" { progresslayer.opacity = 1 let float = (change?[NSKeyValueChangeKey.newKey] as! NSNumber).floatValue progresslayer.frame = CGRect(x: 0, y: cDevice_iPhoneNavBarAndStatusBarHei, width: cScreenWidth * CGFloat(float), height: 3) if float == 1 { weak var weakself = self DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 0.2) { weakself?.progresslayer.opacity = 0 } DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 0.8) { weakself?.progresslayer.frame = CGRect(x: 0, y: cDevice_iPhoneNavBarAndStatusBarHei, width: 0, height: 3) } } } else { super.observeValue(forKeyPath: keyPath, of: object, change: change, context: context) } } public func webView(_ webView: WKWebView, didFinish _: WKNavigation!) { if baseTitle == nil || baseTitle?.count ?? 0 <= 0 { webView.evaluateJavaScript("document.title") { [weak self] (any, _) -> Void in self?.setTitle(title: any as? String) self?.baseTitle = any as? String } } if evaluateJavaScript != nil, (evaluateJavaScript?.count ?? 0) > 0 { webView.evaluateJavaScript(evaluateJavaScript!) { _, _ in } } } public func webView(_ webView: WKWebView, didFail _: WKNavigation!, withError error: Error) { BFLog(message: error) if baseTitle == nil || baseTitle?.count ?? 0 <= 0 { webView.evaluateJavaScript("document.title") { [weak self] (any, _) -> Void in self?.setTitle(title: any as? String) self?.baseTitle = any as? String } } } public func webView(_: WKWebView, didFailProvisionalNavigation _: WKNavigation!, withError _: Error) {} public func webView(_: WKWebView, decidePolicyFor navigationResponse: WKNavigationResponse, decisionHandler: @escaping (WKNavigationResponsePolicy) -> Void) { BFLog(message: "navigationResponse:\(String(describing: navigationResponse))") decisionHandler(.allow) } public func webView(_: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) { BFLog(message: "didStartProvisionalNavigation:\(String(describing: navigation))") } public func webView(_: WKWebView, didReceiveServerRedirectForProvisionalNavigation navigation: WKNavigation!) { BFLog(message: "didReceiveServerRedirectForProvisionalNavigation:\(String(describing: navigation))") } public func webView(_: WKWebView, didCommit navigation: WKNavigation!) { BFLog(message: "\(String(describing: navigation))") } // func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) { // let url : String = navigationAction.request.url?.absoluteString ?? ""; // if(url.count == 0 || url == "about:blank"){ // decisionHandler(.cancel) // return // } // let vc = PQBaseWebViewController.init() // vc.baseUrl = url // navigationController?.pushViewController(vc, animated: true) // BFLog(message: "decidePolicyFor \(String(describing: navigationAction))") // decisionHandler(.allow) // } override public var preferredStatusBarStyle: UIStatusBarStyle { if #available(iOS 13.0, *) { return .darkContent } else { // Fallback on earlier versions return .default } } }