Skip to content

Instantly share code, notes, and snippets.

@joshbetz

joshbetz/Webview.swift

Last active Dec 29, 2020
Embed
What would you like to do?
SwiftUI Webview with a Progress Bar
struct Webview: UIViewControllerRepresentable {
let url: URL
func makeUIViewController(context: Context) -> WebviewController {
let webviewController = WebviewController()
let request = URLRequest(url: self.url, cachePolicy: .returnCacheDataElseLoad)
webviewController.webview.load(request)
return webviewController
}
func updateUIViewController(_ webviewController: WebviewController, context: Context) {
//
}
}
class WebviewController: UIViewController, WKNavigationDelegate {
lazy var webview: WKWebView = WKWebView()
lazy var progressbar: UIProgressView = UIProgressView()
deinit {
self.webview.removeObserver(self, forKeyPath: "estimatedProgress")
self.webview.scrollView.removeObserver(self, forKeyPath: "contentOffset")
}
override func viewDidLoad() {
super.viewDidLoad()
self.webview.navigationDelegate = self
self.view.addSubview(self.webview)
self.webview.frame = self.view.frame
self.webview.translatesAutoresizingMaskIntoConstraints = false
self.view.addConstraints([
self.webview.topAnchor.constraint(equalTo: self.view.topAnchor),
self.webview.bottomAnchor.constraint(equalTo: self.view.bottomAnchor),
self.webview.leadingAnchor.constraint(equalTo: self.view.leadingAnchor),
self.webview.trailingAnchor.constraint(equalTo: self.view.trailingAnchor),
])
self.webview.addSubview(self.progressbar)
self.setProgressBarPosition()
webview.scrollView.addObserver(self, forKeyPath: "contentOffset", options: .new, context: nil)
self.progressbar.progress = 0.1
webview.addObserver(self, forKeyPath: "estimatedProgress", options: .new, context: nil)
}
func setProgressBarPosition() {
self.progressbar.translatesAutoresizingMaskIntoConstraints = false
self.webview.removeConstraints(self.webview.constraints)
self.webview.addConstraints([
self.progressbar.topAnchor.constraint(equalTo: self.webview.topAnchor, constant: self.webview.scrollView.contentOffset.y * -1),
self.progressbar.leadingAnchor.constraint(equalTo: self.webview.leadingAnchor),
self.progressbar.trailingAnchor.constraint(equalTo: self.webview.trailingAnchor),
])
}
// MARK: - Web view progress
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
switch keyPath {
case "estimatedProgress":
if self.webview.estimatedProgress >= 1.0 {
UIView.animate(withDuration: 0.3, animations: { () in
self.progressbar.alpha = 0.0
}, completion: { finished in
self.progressbar.setProgress(0.0, animated: false)
})
} else {
self.progressbar.isHidden = false
self.progressbar.alpha = 1.0
progressbar.setProgress(Float(self.webview.estimatedProgress), animated: true)
}
case "contentOffset":
self.setProgressBarPosition()
default:
super.observeValue(forKeyPath: keyPath, of: object, change: change, context: context)
}
}
}
@OOXXXX

This comment has been minimized.

Copy link

@OOXXXX OOXXXX commented May 22, 2020

Hi, your code is wonderful, but I have some problems when setting the constraints of the web view. Because on iPad, the web view will be scaled. Could you help me to solve the problem? Thanks
CleanShot 2020-0522 -0921@2x

@stevencolvin

This comment has been minimized.

Copy link

@stevencolvin stevencolvin commented Nov 24, 2020

I am also having a problem with constraints, particularly with the bottom restraint. Part of the bottom of the webpage is blocked off, and I am unable to click anything on the bottom portion of the webpage.

@marc-lallias

This comment has been minimized.

Copy link

@marc-lallias marc-lallias commented Dec 2, 2020

https://medium.com/macoclock/how-to-use-webkit-webview-in-swiftui-4b944d04190a

Use this one if you want better constraint management

@joshbetz

This comment has been minimized.

Copy link
Owner Author

@joshbetz joshbetz commented Dec 4, 2020

Updated this with better constraint management, although that example looks nicer in general.

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.