diff --git a/SBrowser/Browser View/BrowserViewController.swift b/SBrowser/Browser View/BrowserViewController.swift index e2ea989..093613d 100644 --- a/SBrowser/Browser View/BrowserViewController.swift +++ b/SBrowser/Browser View/BrowserViewController.swift @@ -19,6 +19,8 @@ class BrowserViewController: UIViewController, private var blockedScriptOrigins = Set() override var canBecomeFirstResponder: Bool { true } + private var loadingObservation: NSKeyValueObservation? + init() { super.init(nibName: nil, bundle: nil) } @@ -53,6 +55,11 @@ class BrowserViewController: UIViewController, // TextField delegate 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 } @@ -94,6 +101,10 @@ class BrowserViewController: UIViewController, } } + func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) { + toolbarController.urlBar.loadProgress = .complete + } + // MARK: UITextField Delegate func textFieldShouldReturn(_ textField: UITextField) -> Bool { diff --git a/SBrowser/Browser View/URLBar.swift b/SBrowser/Browser View/URLBar.swift index 1059bf4..f27dd5b 100644 --- a/SBrowser/Browser View/URLBar.swift +++ b/SBrowser/Browser View/URLBar.swift @@ -12,7 +12,17 @@ class URLBar: UIView let textField = UITextField(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 progressIndicatorView = ProgressIndicatorView() convenience init() { self.init(frame: .zero) @@ -26,6 +36,8 @@ class URLBar: UIView backgroundView.isUserInteractionEnabled = false addSubview(backgroundView) + backgroundView.contentView.addSubview(progressIndicatorView) + textField.backgroundColor = .clear textField.textContentType = .URL textField.keyboardType = .webSearch @@ -40,19 +52,60 @@ class URLBar: UIView 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) return CGSize(width: 1000.0, height: preferredHeight) } - override func layoutSubviews() - { + override func layoutSubviews() { super.layoutSubviews() backgroundView.frame = bounds + progressIndicatorView.frame = backgroundView.contentView.bounds textField.frame = bounds.insetBy(dx: 6.0, dy: 0) 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) } } + +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)) + } +}