Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
WKWebView controller example with progress bar
//
// MyWKWebVC.Swift
// Example
//
// Created by Fahied on 04/01/2017.
//
import Foundation
import UIKit
import WebKit
var myContext = 0
class MyWKWebVC: UIViewController {
var webView: WKWebView!
var package: NSDictionary!
var progressView: UIProgressView!
//init
override func loadView() {
//add webview
webView = WKWebView()
webView.navigationDelegate = self
view = webView
//add progresbar to navigation bar
progressView = UIProgressView(progressViewStyle: .default)
progressView.autoresizingMask = [.flexibleWidth, .flexibleTopMargin]
progressView.tintColor = #colorLiteral(red: 0.6576176882, green: 0.7789518833, blue: 0.2271372974, alpha: 1)
navigationController?.navigationBar.addSubview(progressView)
let navigationBarBounds = self.navigationController?.navigationBar.bounds
progressView.frame = CGRect(x: 0, y: navigationBarBounds!.size.height - 2, width: navigationBarBounds!.size.width, height: 2)
}
//deinit
deinit {
//remove all observers
webView.removeObserver(self, forKeyPath: "title")
webView.removeObserver(self, forKeyPath: "estimatedProgress")
//remove progress bar from navigation bar
progressView.removeFromSuperview()
}
//viewcontroller
override func viewDidLoad() {
webView.load(myRequest())
webView.allowsBackForwardNavigationGestures = true
// // add observer for key path
webView.addObserver(self, forKeyPath: "title", options: .new, context: &myContext)
webView.addObserver(self, forKeyPath: "estimatedProgress", options: .new, context: &myContext)
}
//actions
func doneTapped() {
//Routing is your class handle view routing in your app
Routing.showAnotherVC(fromVC: self)
}
//observer
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
guard let change = change else { return }
if context != &myContext {
super.observeValue(forKeyPath: keyPath, of: object, change: change, context: context)
return
}
if keyPath == "title" {
if let title = change[NSKeyValueChangeKey.newKey] as? String {
self.navigationItem.title = title
}
return
}
if keyPath == "estimatedProgress" {
if let progress = (change[NSKeyValueChangeKey.newKey] as AnyObject).floatValue {
progressView.progress = progress;
}
return
}
}
//compute your url request
func myRequest() -> URLRequest {
return URLRequest(url: (URL(string: "https://google.com")
}
func addDoneButton() {
let done = UIBarButtonItem(barButtonSystemItem: .done, target: self, action: #selector(doneTapped))
navigationItem.rightBarButtonItems = [done]
}
func hideBackButton() {
navigationItem.setHidesBackButton(true, animated: false)
}
}
extension PaymentVC: WKNavigationDelegate {
//WKNavigationDelegate
func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
if let url = navigationAction.request.url {
if url.absoluteString.contains("/something") {
// if url contains something; take user to native view controller
Routing.showAnotherVC(fromVC: self)
decisionHandler(.cancel)
} else if url.absoluteString.contains("done") {
//in case you want to stop user going back
hideBackButton()
addDoneButton()
decisionHandler(.allow)
} else if url.absoluteString.contains("AuthError") {
//in case of erros, show native allerts
}
else{
decisionHandler(.allow)
}
}
}
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
progressView.isHidden = true
}
func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) {
progressView.isHidden = false
}
}
@tinusg

This comment has been minimized.

Copy link

tinusg commented Sep 22, 2017

Looks great, I used parts of it. But I think you have to add the observers before webview.load()?

@gkmrakesh

This comment has been minimized.

Copy link

gkmrakesh commented Jan 2, 2018

Can you please help solving "Block Based KVO Violation: Prefer the new block based KVO API with keypaths when using Swift 3.2 or later. (block_based_kvo)" warning while using wkwebview progress bar

@jp-dubey07

This comment has been minimized.

Copy link

jp-dubey07 commented Apr 10, 2018

Great! The use of observer solved my problem i.e. webview content is loaded first followed by title for navigation item.

@jp-dubey07

This comment has been minimized.

Copy link

jp-dubey07 commented Apr 10, 2018

However, use of this function throws a warning Block based KVO violation.. Refer screenshot for detail.

screen shot 2018-04-10 at 11 54 51 am

Any fix for this?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.