Load Html Text In Wkwebview
Solution 1:
Here is a modified version of your ViewController
class:
import UIKit
import WebKit
classViewController: UIViewController, UIScrollViewDelegate, WKNavigationDelegate {
@IBOutletweakvar webView: WKWebView!
@IBOutletweakvar pagesLabel: UILabel!
var readBookNumber =0let headerString ="<meta name=\"viewport\" content=\"initial-scale=1.0\" />"var textSize =3var contentSize: CGSize= .zero
overridefuncviewDidLoad() {
super.viewDidLoad()
// Web View Delegate
webView.scrollView.delegate =self
webView.navigationDelegate =self
webView.scrollView.isPagingEnabled =true
webView.scrollView.alwaysBounceVertical =false
webView.scrollView.showsHorizontalScrollIndicator =true
webView.scrollView.showsVerticalScrollIndicator =false
webView.scrollView.panGestureRecognizer.isEnabled =false
webView.scrollView.pinchGestureRecognizer?.isEnabled =false
webView.scrollView.bouncesZoom =falseself.webView.isOpaque =false;
self.webView.backgroundColor = .clear
// Load Filedo {
guardlet filePath =Bundle.main.path(forResource: "0", ofType: "html")
else {
print ("File reading error")
return
}
var content =tryString(contentsOfFile: filePath, encoding: .utf8)
let baseUrl =URL(fileURLWithPath: filePath)
content.changeHtmlStyle(font: "Iowan-Old-Style", fontSize: 4, fontColor: "black")
webView.loadHTMLString(headerString+content, baseURL: baseUrl)
// add content size Observer
webView.scrollView.addObserver(self, forKeyPath: #keyPath(UIScrollView.contentSize), options: .new, context: nil)
}
catch {
print ("File HTML error")
}
}
overridefuncobserveValue(forKeyPathkeyPath: String?, ofobject: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
if (keyPath ==#keyPath(UIScrollView.contentSize)) {
let contentSize = webView.scrollView.contentSize
if contentSize !=self.contentSize {
self.contentSize = contentSize
DispatchQueue.main.async {
self.webView.scrollView.contentOffset.x =CGFloat(UserDefaults.standard.integer(forKey: "pageToLoad"))
}
}
}
}
// MARK: - webView Scroll ViewfuncscrollViewDidEndDecelerating(_scrollView: UIScrollView) {
self.stoppedScrolling()
}
funcscrollViewDidEndDragging(_scrollView: UIScrollView, willDeceleratedecelerate: Bool) {
if!decelerate {
self.stoppedScrolling()
}
}
funcscrollViewDidScroll(_scrollView: UIScrollView) {
var currentPage =Int((webView.scrollView.contentOffset.x / webView.scrollView.frame.size.width) +1)
let pageCount =Int(webView.scrollView.contentSize.width / webView.scrollView.frame.size.width)
if currentPage ==0 {
currentPage =1
} else {
}
if!webView.isHidden {
pagesLabel.text ="\( currentPage ) из \( pageCount )"
} else {
pagesLabel.text =""
}
}
funcscrollViewWillBeginZooming(_scrollView: UIScrollView, withview: UIView?) {
webView.scrollView.pinchGestureRecognizer?.isEnabled =false
}
funcstoppedScrolling() {
let pageToLoad =Int((webView.scrollView.contentOffset.x))
UserDefaults.standard.set(pageToLoad, forKey: "pageToLoad")
}
// MARK: - loading webViewfuncwebView(_webView: WKWebView, didStartProvisionalNavigationnavigation: WKNavigation!) {
}
funcwebView(_webView: WKWebView, didFinishnavigation: WKNavigation!) {
// Маленькая задержка, которую мне хотелось бы использовать/*DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
self.webView.scrollView.contentOffset.x = CGFloat(UserDefaults.standard.integer(forKey: "pageToLoad"))
}*/// Большая задержка, которую мне приходится использовать// don't do this here... we'll do the "auto-scroll" inside the change contentSize Observer//DispatchQueue.main.asyncAfter(deadline: .now() + 2.0) {// self.webView.scrollView.contentOffset.x = CGFloat(UserDefaults.standard.integer(forKey: "pageToLoad"))//}
}
funcwebView(_webView: WKWebView, didFailnavigation: WKNavigation!, withErrorerror: Error) {
}
}
extensionString {
mutatingfuncchangeHtmlStyle(font: String, fontSize: Int, fontColor: String) {
let style ="<font face='\(font)' size='\(fontSize)' color= '\(fontColor)'>%@"self=String(format: style, self)
}
}
It uses an Observer to watch the contentSize
change in the web view's scroll view.
Note that it is called multiple times - with different values - during the load and layout process, but it may do the job for you.
Also note, though, that you'll need to account for changes in the web view size - for example, if the user rotates the device. So... more to do, but this may get you going.
Solution 2:
You can add a property observer and watch the estimated progress of the page load:
overridefuncviewDidLoad() {
super.viewDidLoad()
webView.addObserver(self, forKeyPath: #keyPath(WKWebView.estimatedProgress), options: .new, context: nil)
....
}
and observe when the page is being loaded:
overridefuncobserveValue(forKeyPathkeyPath: String?, ofobject: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
if (keyPath =="estimatedProgress") {
if webView.estimatedProgress ==1.0 {
print ("page loaded")
}
}
}
You may be able to predict based on the page number how far into the loading process you need to be before you set your offset.
Solution 3:
Instead of observing WKWebView.estimatedProgress
you should observe UIScrollView.contentSize
because you need to scroll to an available position e.g.:
var positionY: CGFloat=1000var contentSize =CGSize(width: 0, height: 0)
overridefuncviewDidLoad() {
super.viewDidLoad()
...
webView?.scrollView.addObserver(self, forKeyPath: #keyPath(UIScrollView.contentSize), options: .new, context: nil)
}
overridefuncobserveValue(forKeyPathkeyPath: String?, ofobject: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
if (keyPath ==#keyPath(UIScrollView.contentSize)) {
iflet contentSize = webView?.scrollView.contentSize, contentSize !=self.contentSize {
self.contentSize = contentSize
if contentSize.height > positionY {
webView?.scrollView.setContentOffset(CGPoint(x: 0, y: positionY), animated: true)
}
}
}
}
Post a Comment for "Load Html Text In Wkwebview"