はじめに
資料
WebView の進捗を KVO する
WebView の読み込み進捗(estimatedProgress)を KVO する最小のコードは以下。これで正しく進捗を得ることを確認できた。
var observation: NSKeyValueObservation?
observation = webView.observe(\.estimatedProgress, options: .new){_, change in
print("progress=\(String(describing: change.newValue))")
}
UI を実装する
WebView の進捗を得ることを確認できたので、それっぽい UI を実装してみる。要件は以下だ。
- WKWebView 上部に UIProgressView で進捗を表示する
- 進捗が 1.0 になったら(読み込みが完了したら)、プログレスの表示をフェードアウトして消したい(Chrome とか Safari のように)
- プログレスの色をデフォルトの青から変えてみたい
コードは以下。
class ViewController: UIViewController, WKNavigationDelegate {
@IBOutlet weak var webView: WKWebView!
@IBOutlet weak var progressView: UIProgressView!
private var observation: NSKeyValueObservation?
private var colorCnt = 0
private let colorArray: [UIColor] = [
.blue,
.green,
.yellow,
.red,
]
override func viewDidLoad() {
super.viewDidLoad()
webView.load(URLRequest(url: URL(string: "https://www.kantei.go.jp/")!))
progressView.progressTintColor = colorArray[colorCnt]
colorCnt = colorCnt + 1
observation = webView.observe(\.estimatedProgress, options: .new){_, change in
print("progress=\(String(describing: change.newValue))")
self.progressView.setProgress(Float(change.newValue!), animated: true)
if change.newValue! >= 1.0 {
UIView.animate(withDuration: 1.0,
delay: 0.0,
options: [.curveEaseIn],
animations: {
self.progressView.alpha = 0.0
}, completion: { (finished: Bool) in
self.progressView.progressTintColor = self.colorArray[self.colorCnt]
self.colorCnt = self.colorCnt + 1
if self.colorCnt >= self.colorArray.count {
self.colorCnt = 0
}
self.progressView.setProgress(0, animated: false)
})
}
else {
self.progressView.alpha = 1.0
}
}
}
}
動作イメージ
上記のコードを実行するとこんな感じ。Good ですね。
完全なサンプルプロジェクト
ビルドできる完全なサンプルプロジェクトは GitHub にある