Load progress indicator
This commit is contained in:
@@ -19,6 +19,8 @@ class BrowserViewController: UIViewController,
|
|||||||
private var blockedScriptOrigins = Set<String>()
|
private var blockedScriptOrigins = Set<String>()
|
||||||
override var canBecomeFirstResponder: Bool { true }
|
override var canBecomeFirstResponder: Bool { true }
|
||||||
|
|
||||||
|
private var loadingObservation: NSKeyValueObservation?
|
||||||
|
|
||||||
init() {
|
init() {
|
||||||
super.init(nibName: nil, bundle: nil)
|
super.init(nibName: nil, bundle: nil)
|
||||||
}
|
}
|
||||||
@@ -53,6 +55,11 @@ class BrowserViewController: UIViewController,
|
|||||||
// TextField delegate
|
// TextField delegate
|
||||||
toolbarController.urlBar.textField.delegate = self
|
toolbarController.urlBar.textField.delegate = self
|
||||||
|
|
||||||
|
// Load progress
|
||||||
|
loadingObservation = webView.observe(\.estimatedProgress) { (webView, observedChange) in
|
||||||
|
self.toolbarController.urlBar.loadProgress = .loading(progress: webView.estimatedProgress)
|
||||||
|
}
|
||||||
|
|
||||||
self.view = browserView
|
self.view = browserView
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -94,6 +101,10 @@ class BrowserViewController: UIViewController,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
|
||||||
|
toolbarController.urlBar.loadProgress = .complete
|
||||||
|
}
|
||||||
|
|
||||||
// MARK: UITextField Delegate
|
// MARK: UITextField Delegate
|
||||||
|
|
||||||
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
|
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
|
||||||
|
|||||||
@@ -12,7 +12,17 @@ class URLBar: UIView
|
|||||||
let textField = UITextField(frame: .zero)
|
let textField = UITextField(frame: .zero)
|
||||||
let refreshButton = UIButton(frame: .zero)
|
let refreshButton = UIButton(frame: .zero)
|
||||||
|
|
||||||
|
public enum LoadProgress {
|
||||||
|
case complete
|
||||||
|
case loading(progress: Double)
|
||||||
|
}
|
||||||
|
|
||||||
|
public var loadProgress: LoadProgress = .complete {
|
||||||
|
didSet { updateProgressIndicator() }
|
||||||
|
}
|
||||||
|
|
||||||
private let backgroundView = UIVisualEffectView(effect: UIBlurEffect(style: .systemThickMaterial))
|
private let backgroundView = UIVisualEffectView(effect: UIBlurEffect(style: .systemThickMaterial))
|
||||||
|
private let progressIndicatorView = ProgressIndicatorView()
|
||||||
|
|
||||||
convenience init() {
|
convenience init() {
|
||||||
self.init(frame: .zero)
|
self.init(frame: .zero)
|
||||||
@@ -26,6 +36,8 @@ class URLBar: UIView
|
|||||||
backgroundView.isUserInteractionEnabled = false
|
backgroundView.isUserInteractionEnabled = false
|
||||||
addSubview(backgroundView)
|
addSubview(backgroundView)
|
||||||
|
|
||||||
|
backgroundView.contentView.addSubview(progressIndicatorView)
|
||||||
|
|
||||||
textField.backgroundColor = .clear
|
textField.backgroundColor = .clear
|
||||||
textField.textContentType = .URL
|
textField.textContentType = .URL
|
||||||
textField.keyboardType = .webSearch
|
textField.keyboardType = .webSearch
|
||||||
@@ -40,19 +52,60 @@ class URLBar: UIView
|
|||||||
addSubview(refreshButton)
|
addSubview(refreshButton)
|
||||||
}
|
}
|
||||||
|
|
||||||
override var intrinsicContentSize: CGSize
|
private func updateProgressIndicator() {
|
||||||
{
|
UIView.animate(withDuration: 0.4) {
|
||||||
|
switch self.loadProgress {
|
||||||
|
case .complete:
|
||||||
|
self.progressIndicatorView.progress = 1.0
|
||||||
|
self.progressIndicatorView.alpha = 0.0
|
||||||
|
case .loading(let progress):
|
||||||
|
self.progressIndicatorView.progress = progress
|
||||||
|
self.progressIndicatorView.alpha = 1.0
|
||||||
|
}
|
||||||
|
} completion: { _ in
|
||||||
|
if case LoadProgress.complete = self.loadProgress {
|
||||||
|
// Reset back to zero
|
||||||
|
self.progressIndicatorView.progress = 0.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override var intrinsicContentSize: CGSize {
|
||||||
let preferredHeight = CGFloat(34)
|
let preferredHeight = CGFloat(34)
|
||||||
return CGSize(width: 1000.0, height: preferredHeight)
|
return CGSize(width: 1000.0, height: preferredHeight)
|
||||||
}
|
}
|
||||||
|
|
||||||
override func layoutSubviews()
|
override func layoutSubviews() {
|
||||||
{
|
|
||||||
super.layoutSubviews()
|
super.layoutSubviews()
|
||||||
backgroundView.frame = bounds
|
backgroundView.frame = bounds
|
||||||
|
progressIndicatorView.frame = backgroundView.contentView.bounds
|
||||||
textField.frame = bounds.insetBy(dx: 6.0, dy: 0)
|
textField.frame = bounds.insetBy(dx: 6.0, dy: 0)
|
||||||
|
|
||||||
let refreshButtonSize = CGSize(width: textField.frame.height, height: textField.frame.height)
|
let refreshButtonSize = CGSize(width: textField.frame.height, height: textField.frame.height)
|
||||||
refreshButton.frame = CGRect(origin: CGPoint(x: bounds.width - refreshButtonSize.width, y: 0), size: refreshButtonSize)
|
refreshButton.frame = CGRect(origin: CGPoint(x: bounds.width - refreshButtonSize.width, y: 0), size: refreshButtonSize)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class ProgressIndicatorView: UIView
|
||||||
|
{
|
||||||
|
public var progress: Double = 0.0 {
|
||||||
|
didSet { layoutSubviews() }
|
||||||
|
}
|
||||||
|
|
||||||
|
private let progressFillView = UIView(frame: .zero)
|
||||||
|
|
||||||
|
convenience init() {
|
||||||
|
self.init(frame: .zero)
|
||||||
|
|
||||||
|
progressFillView.backgroundColor = .systemBlue
|
||||||
|
progressFillView.alpha = 0.3
|
||||||
|
addSubview(progressFillView)
|
||||||
|
}
|
||||||
|
|
||||||
|
override func layoutSubviews() {
|
||||||
|
super.layoutSubviews()
|
||||||
|
|
||||||
|
let width = CGFloat(progress) * bounds.width
|
||||||
|
progressFillView.frame = CGRect(origin: .zero, size: CGSize(width: width, height: bounds.height))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user