WKWebViewのLoading表示
どの手段が適切かな🤔
と気になったのでまとめてみました
1. StatusBarに表示
networkactivityindicatorvisibleを活用
ViewController.swift
@IBOutlet weak var webView: WKWebView!
override func viewDidLoad() {
super.viewDidLoad()
let request = URLRequest(url: URL(string: "https://koooootake.com/")!)
webView.load(request)
webView.navigationDelegate = self
}
private func startIndicator() {
UIApplication.shared.isNetworkActivityIndicatorVisible = true
}
private func stopIndicator() {
UIApplication.shared.isNetworkActivityIndicatorVisible = false
}
WKNavigationDelegateを実装
ViewController.swift
extension StatusBarLoadingViewController: WKNavigationDelegate {
func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) {
startIndicator()
}
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
stopIndicator()
}
func webView(_ webView: WKWebView, didFail navigation: WKNavigation!, withError error: Error) {
stopIndicator()
}
func webView(_ webView: WKWebView, didFailProvisionalNavigation navigation: WKNavigation!, withError error: Error) {
stopIndicator()
}
}
ただし、ノッジのあるiPhoneXシリーズだとくるくるが表示されないためイマイチ😢
2. UIActivityIndicatorViewで表示
ViewController.swift
@IBOutlet weak var webView: WKWebView!
@IBOutlet weak var activityIndicatorView: UIActivityIndicatorView!
override func viewDidLoad() {
super.viewDidLoad()
let request = URLRequest(url: URL(string: "https://koooootake.com/")!)
webView.load(request)
webView.navigationDelegate = self
activityIndicatorView.hidesWhenStopped = true
}
private func startIndicator() {
activityIndicatorView.startAnimating()
}
private func stopIndicator() {
activityIndicatorView.stopAnimating()
}
と1. と同じくWKNavigationDelegateを実装
シンプルに読み込み中であることが伝わる😀
3. UIProgressViewで受信状況を表示
ViewController.swift
@IBOutlet weak var webView: WKWebView!
private var progressView = UIProgressView(progressViewStyle: .bar)
override func viewDidLoad() {
super.viewDidLoad()
let request = URLRequest(url: URL(string: "https://koooootake.com/")!)
webView.load(request)
setupProgressView()
}
private func setupProgressView() {
guard let navigationBarH = self.navigationController?.navigationBar.frame.size.height else {
assertionFailure()
return
}
progressView = UIProgressView(frame: CGRect(x: 0.0, y: navigationBarH, width: self.view.frame.size.width, height: 0.0))
navigationController?.navigationBar.addSubview(progressView)
//変更を検知
webView.addObserver(self, forKeyPath: #keyPath(WKWebView.isLoading), options: .new, context: nil)
webView.addObserver(self, forKeyPath: #keyPath(WKWebView.estimatedProgress), options: .new, context: nil)
}
検知した変更をUIに反映
ViewController.swift
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey: Any]?, context: UnsafeMutableRawPointer?) {
guard let keyPath = keyPath else {
assertionFailure()
return
}
switch keyPath {
case #keyPath(WKWebView.isLoading):
if webView.isLoading {
progressView.alpha = 1.0
progressView.setProgress(0.1, animated: true)
} else {
UIView.animate(withDuration: 0.3, animations: {
self.progressView.alpha = 0.0
}, completion: { _ in
self.progressView.setProgress(0.0, animated: false)
})
}
case #keyPath(WKWebView.estimatedProgress):
self.progressView.setProgress(Float(webView.estimatedProgress), animated: true)
default:
//do nothing
break
}
}
あとどれくらいで終わるか伝わるので、待機ストレスがなくなる予感ですねねね🤩
おわりに
引っ張ってリロードとの表示のバッティングに注意!
オシャレなアニメーションライブラリと組み合わせてもなおよし
適切なローディング表示を選択しよう🙋♂️
Swift4