Files
yingmeng-ios-switf/yinmeng-ios/Base/Web/WebViewController.swift
2024-03-22 11:54:23 +08:00

228 lines
6.5 KiB
Swift
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//
// WebViewController.swift
// yinmeng-ios
//
// Created by yinmeng on 2024/2/26.
//
import UIKit
import WebKit
class WebViewWeakScriptMessage: NSObject, WKScriptMessageHandler {
private(set) weak var target: WKScriptMessageHandler?
required init(target: WKScriptMessageHandler?) {
self.target = target
}
func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
target?.userContentController(userContentController, didReceive: message)
}
}
class WebViewController: BaseViewController {
typealias OnReceiveMessage = (_ msg: WKScriptMessage) -> Void
private(set) lazy var webview = makeWebView()
private(set) var progressView = UIProgressView()
private lazy var userContentController = WKUserContentController()
private var callbacks: [String: [OnReceiveMessage]] = [:]
private(set) weak var navigationDelegate: WKNavigationDelegate?
private(set) var url: String?
var isHalf:Bool = false
convenience init(
url: String?,
navigationDelegate: WKNavigationDelegate? = nil,isHalf:Bool = false
) {
self.init(nibName: nil, bundle: nil)
self.url = url
self.isHalf = isHalf
if var url = url {
if !url.hasPrefix("http") {
url = "\(H5_URL)/\(url)"
}
self.url = url
}
self.navigationDelegate = navigationDelegate
}
override func viewDidLoad() {
super.viewDidLoad()
loadSubViews()
loadWebView()
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
addObserve()
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
removeObserve()
}
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
view.bringSubviewToFront(progressView)
}
private func loadSubViews() {
if self.isHalf{
let bakcBtn = UIButton()
bakcBtn.addTarget(self, action: #selector(dissViewAction), for: .touchUpInside)
view.addSubview(bakcBtn)
bakcBtn.snp.makeConstraints { make in
make.edges.equalTo(view)
}
view.addSubview(webview)
view.addSubview(progressView)
progressView.snp.makeConstraints { make in
make.top.equalTo(view).offset(0)
make.left.right.equalTo(view).offset(0)
make.height.equalTo(1)
}
view.backgroundColor = .clear
webview.snp.makeConstraints { make in
make.left.bottom.right.equalTo(view)
make.height.equalTo(ScreenHeight * 0.65)
}
}else{
view.addSubview(webview)
view.addSubview(progressView)
progressView.snp.makeConstraints { make in
make.top.equalTo(view).offset(0)
make.left.right.equalTo(view).offset(0)
make.height.equalTo(1)
}
webview.snp.makeConstraints { make in
make.top.equalTo(view).offset(1)
make.left.right.bottom.equalTo(view)
}
}
progressView.trackTintColor = .clear
progressView.transform = .init(scaleX: 1, y: 1.5)
progressView.alpha = 0
}
@objc func dissViewAction(){
self.dismiss(animated: true)
}
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
if let object = object as? WKWebView, object == webview {
if keyPath == "estimatedProgress" {
progressView.setProgress(Float(webview.estimatedProgress), animated: true)
return
}
}
if keyPath == "title" {
title = webview.title
return
}
}
func addObserve() {
//KVOWKWebViewestimatedProgress
webview.addObserver(self, forKeyPath: "estimatedProgress", context: nil)
//KVOtitle
webview.addObserver(self, forKeyPath: "title", context: nil)
}
func removeObserve() {
webview.removeObserver(self, forKeyPath: "estimatedProgress")
webview.removeObserver(self, forKeyPath: "title")
}
func loadWebView() {
guard let url = url,
let theUrl = URL(string: url),
let _ = theUrl.scheme,
let _ = theUrl.host else {
return
}
webview.load(URLRequest(url: theUrl))
}
func reloadWebViewWithUrl(_ url: String) {
self.url = url
loadWebView()
}
func makeWebView() -> WKWebView {
let configuration = WKWebViewConfiguration()
configuration.mediaTypesRequiringUserActionForPlayback = .all
configuration.allowsInlineMediaPlayback = true
configuration.allowsPictureInPictureMediaPlayback = true
configuration.selectionGranularity = .character
configuration.userContentController = userContentController
let preferences = WKPreferences()
if #available(iOS 14, *) {
let webpagePreferences = WKWebpagePreferences()
webpagePreferences.allowsContentJavaScript = true
configuration.defaultWebpagePreferences = webpagePreferences
} else {
preferences.javaScriptEnabled = true
}
preferences.javaScriptCanOpenWindowsAutomatically = true
preferences.minimumFontSize = 10
configuration.preferences = preferences
let webview = WKWebView(frame: UIScreen.main.bounds, configuration: configuration)
webview.navigationDelegate = self
return webview
}
func dicValueString(_ dic:[String:Any]) ->String? {
let data = try? JSONSerialization.data(withJSONObject: dic,options: [])
let str = String(data: data!,encoding:String.Encoding.utf8)
return str
}
}
extension WebViewController: WKScriptMessageHandler {
func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
//TODO: h5
}
}
extension WebViewController: WKNavigationDelegate {
func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) {
progressView.alpha = 1
navigationDelegate?.webView?(webview, didStartProvisionalNavigation: navigation)
}
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
UIView.animate(withDuration: 0.2) {
self.progressView.alpha = 0
}
navigationDelegate?.webView?(webview, didFinish: navigation)
}
func webView(_ webView: WKWebView, didFailProvisionalNavigation navigation: WKNavigation!, withError error: Error) {
UIView.animate(withDuration: 0.2) {
self.progressView.alpha = 0
}
navigationDelegate?.webView?(webView, didFailProvisionalNavigation: navigation, withError: error)
}
}