Skip to content

Instantly share code, notes, and snippets.

@strzempa
Last active October 11, 2019 05:22
Show Gist options
  • Save strzempa/a523640d463e781da66dcd3289d50ba8 to your computer and use it in GitHub Desktop.
Save strzempa/a523640d463e781da66dcd3289d50ba8 to your computer and use it in GitHub Desktop.
WKWebViewController with secure progress observation, progressView and activityIndicatorView
import UIKit
import WebKit
open class ProgressObservableWebViewController: UIViewController, WKWebViewProgressObservable {
@IBOutlet weak public var webView: WKWebView!
public var webViewProgressObservation: Any?
private let progressView: UIProgressView = {
let view = UIProgressView(progressViewStyle: .default)
view.progressTintColor = .blue
view.translatesAutoresizingMaskIntoConstraints = false
return view
}()
private let activityIndicatorView: UIActivityIndicatorView = {
let activityView = UIActivityIndicatorView(style: .gray)
activityView.startAnimating()
activityView.translatesAutoresizingMaskIntoConstraints = false
activityView.hidesWhenStopped = true
return activityView
}()
override open func viewDidLoad() {
super.viewDidLoad()
setupUI()
startWebViewProgressObservation { [weak self] value in
self?.progressView.progress = Float(value)
}
}
public func showLoading() {
activityIndicatorView.startAnimating()
UIView.animate(withDuration: 0.5, delay: 0, options: .curveEaseInOut, animations: {
self.progressView.alpha = 1
}, completion: nil)
}
public func hideLoading() {
activityIndicatorView.stopAnimating()
UIView.animate(withDuration: 0.5, delay: 0.5, options: .curveEaseInOut, animations: {
self.progressView.alpha = 0
}, completion: nil)
}
}
private extension ProgressObservableWebViewController {
func setupUI() {
[progressView].forEach { self.view.addSubview($0) }
progressView.leadingAnchor.constraint(equalTo: webView.leadingAnchor).isActive = true
progressView.trailingAnchor.constraint(equalTo: webView.trailingAnchor).isActive = true
progressView.topAnchor.constraint(equalTo: webView.safeAreaLayoutGuide.topAnchor).isActive = true
progressView.heightAnchor.constraint(equalToConstant: 4).isActive = true
webView.embed(activityIndicatorView)
activityIndicatorView.centerXAnchor.constraint(equalTo: webView.centerXAnchor).isActive = true
activityIndicatorView.centerYAnchor.constraint(equalTo: webView.centerYAnchor).isActive = true
}
}
public protocol WKWebViewProgressObservable: AnyObject {
var webView: WKWebView! { get set }
var webViewProgressObservation: Any? { get set }
typealias WebViewProgressObservableCompletionHandler = (_ value: Double) -> Void
func startWebViewProgressObservation(completion: WebViewProgressObservableCompletionHandler?)
func stopWebViewProgressObservation()
}
public extension WKWebViewProgressObservable {
func startWebViewProgressObservation(completion: WebViewProgressObservableCompletionHandler?) {
webViewProgressObservation = webView.observe(\.estimatedProgress) { (webView, _) in
completion?(webView.estimatedProgress)
}
}
func stopWebViewProgressObservation() {
webViewProgressObservation = nil
}
}
public extension UIView {
func embed(_ view: UIView) {
view.translatesAutoresizingMaskIntoConstraints = false
addSubview(view)
view.leftAnchor.constraint(equalTo: leftAnchor).isActive = true
view.rightAnchor.constraint(equalTo: rightAnchor).isActive = true
view.topAnchor.constraint(equalTo: topAnchor).isActive = true
view.bottomAnchor.constraint(equalTo: bottomAnchor).isActive = true
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment