在WKWebView中加载html文本

2024-01-11

我用这个代码来加载我的html包含文本的文件WKWebView:

do {
   guard let filePath = Bundle.main.path(forResource: "\(readBookNumber)", ofType: "html")
       else { 
           print ("File reading error")
           return
       }
   var content =  try String(contentsOfFile: filePath, encoding: .utf8)
   let baseUrl = URL(fileURLWithPath: filePath)
            
   content.changeHtmlStyle(font: "Iowan-Old-Style", fontSize:  UserDefaults.standard.integer(forKey: "textSize"), fontColor: textColor)
   webView.loadHTMLString(headerString+content, baseURL: baseUrl)
}
catch {
    print ("File HTML error")
}

这段代码用于加载用户上次停止阅读的页面:

self.webView.scrollView.contentOffset.x = CGFloat(UserDefaults.standard.integer(forKey: "pageToLoad"))

我在此方法中使用加载最后一页的代码:

func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
    DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
         self.webView.scrollView.contentOffset.x = CGFloat(UserDefaults.standard.integer(forKey: "pageToLoad"))
    }
}

一开始我用的是deadline: .now() + 0.1,但这没有用。因为最后阅读的页面是最初加载的,几秒钟后我在第一页上看到了我的文本。我把它改为deadline: .now() + 0.5并且文本从最后一页读取时加载良好。它有 700 页。但现在我想加载另一篇 1700 页的文本。我和第一次一样遇到同样的问题。我可以改变deadline: .now() + 1.0我的文本会加载得很好。但我认为这不是最好的解决方案。我在 iPhone X 上运行它。但也许如果我在 iPad mini 2 上运行它,我应该改变deadline: .now() + 10.0因为iPad mini 2不是很强大。如何解决问题?

基于@DPrice代码更新:

如果我使用这段代码:

override func viewDidLoad() {
    super.viewDidLoad()
    webView.addObserver(self, forKeyPath: #keyPath(WKWebView.estimatedProgress), options: .new, context: nil)

....
}

override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
    if (keyPath == "estimatedProgress") {
        if webView.estimatedProgress == 1.0 {
            self.webView.scrollView.contentOffset.x = CGFloat(UserDefaults.standard.integer(forKey: "pageToLoad\(self.readBookNumber)"))
        }
    }
}

我的结果与我的代码相同。

但如果我使用这段代码:

override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
    if (keyPath == "estimatedProgress") {
        if webView.estimatedProgress == 1.0 {
            DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
                self.webView.scrollView.contentOffset.x = CGFloat(UserDefaults.standard.integer(forKey: "pageToLoad\(self.readBookNumber)"))
            }
        }
    }
}

一切正常。我的最后一页加载正常。但这并不能解决我的问题。


这是您的修改版本ViewController class:

import UIKit
import WebKit

class ViewController: UIViewController, UIScrollViewDelegate, WKNavigationDelegate {
    
    @IBOutlet weak var webView: WKWebView!
    @IBOutlet weak var pagesLabel: UILabel!
    
    var readBookNumber = 0
    let headerString = "<meta name=\"viewport\" content=\"initial-scale=1.0\" />"
    var textSize = 3

    var contentSize: CGSize = .zero

    override func viewDidLoad() {
        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 = false
        
        self.webView.isOpaque = false;
        self.webView.backgroundColor = .clear
        
        // Load File
        
        do {
            guard let filePath = Bundle.main.path(forResource: "0", ofType: "html")
                else {
                    print ("File reading error")
                    return
                }
            var content =  try String(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")
        }
    }
    
    override func observeValue(forKeyPath keyPath: String?, of object: 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 View
    
    func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
        self.stoppedScrolling()
    }

    func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) {
        if !decelerate {
            self.stoppedScrolling()
        }
    }
    
    func scrollViewDidScroll(_ 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 = ""
        }
    }
    
    func scrollViewWillBeginZooming(_ scrollView: UIScrollView, with view: UIView?) {
        webView.scrollView.pinchGestureRecognizer?.isEnabled = false
    }

    func stoppedScrolling() {
        let pageToLoad = Int((webView.scrollView.contentOffset.x))
        UserDefaults.standard.set(pageToLoad, forKey: "pageToLoad")
    }
    
    // MARK: - loading webView

    func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) {
    }
    
    func webView(_ webView: WKWebView, didFinish navigation: 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"))
        //}
    }

    func webView(_ webView: WKWebView, didFail navigation: WKNavigation!, withError error: Error)  {
    }


}

extension String {
  mutating func changeHtmlStyle(font: String, fontSize: Int, fontColor: String) {
    let style = "<font face='\(font)' size='\(fontSize)' color= '\(fontColor)'>%@"
    self = String(format: style, self)
  }
}

它使用观察者来观察contentSize更改网页视图的滚动视图。

请注意,在加载和布局过程中,它会被多次调用(使用不同的值),但它可能会为您完成这项工作。

但还要注意,您需要考虑网络视图大小的变化 - 例如,如果用户旋转设备。所以……还有更多的事情要做,但这可能会让你继续前进。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在WKWebView中加载html文本 的相关文章

  • iOS 上关键 ClientState 警告的默认访问速度缓慢

    在测试我的 iOS 应用程序时 我收到 对关键 ClientState 的默认访问速度慢 耗时 0 034635 秒 容差为 0 020000 警告 它似乎是间歇性发生的 我试图环顾四周看看它是关于什么的 但我并不完全确定 任何帮助表示赞赏
  • 在 Xcode 中查找未使用的文件

    我最近开始开发一个新应用程序 它基本上是我以前制作的应用程序的副本 但做了一些更改 为了制作这个新应用程序 我复制了旧应用程序并删除了一些不需要的内容 我想知道 有没有办法知道 Xcode 中正在使用哪些类文件 或者有什么关于如何查找未使用
  • Ionic 2:隐藏滚动条并继续滚动

    我只想hide滚动条 在需要滚动的页面中 我正在使用离子2 My 不工作解决方案 scroll content bar overflow hidden 此解决方案隐藏滚动条but使屏幕不可滚动 首先 改变浏览器的自然行为和预期的用户体验是一
  • Swift 中计算只读属性与函数

    在 Swift WWDC 简介会话中 只读属性description被证明 class Vehicle var numberOfWheels 0 var description String return numberOfWheels wh
  • 从选择 onChange 调用 javascript 函数 [重复]

    这个问题在这里已经有答案了 所以我有一个简单的 HTML 选择框和一个 javascript 警报功能 我希望选择框有一个 onchange 事件来调用 javascript 警报函数 这是我到目前为止所拥有的 HTML div Type
  • 检测 Webkit/Chrome 中 HTML5 数字控件更改的事件?

    HTML5 为我们提供了一些新的输入元素 例如
  • 从字典创建 Swift 对象

    如何根据 Swift 字典中的查找值动态实例化类型 希望这对其他人有用 我们需要进行一些研究才能弄清楚这一点 目标是避免巨大的 if 或 switch 语句从值创建每个对象类型的反模式 class NamedItem CustomStrin
  • Bootstrap 响应式表格在 iOS 设备上无法垂直滚动

    这就是我所拥有的 div class table responsive table class table style background transparent table div 我正在使用以下 bootstrap css 文件 ht
  • 如何使用CSS缩放图像以填充div并保持纵横比?

    我想用一个 div 填充img 保持纵横比并根据需要拉伸宽度或高度以适应 div style width 80px height 80px img src div 我怎样才能实现它 如果图像不是二次方的 则必须将其 放大 并根据哪一侧较大而
  • Firefox 忽略 CSS 中的最小高度

    由于某些原因 最小高度在 Firefox 上不起作用 我尝试在 body 上设置 min height 但 Firefox 完全忽略了它 由于我的页面是动态的 我不能只将高度设置为 100 我应该怎么办 body border 1px so
  • iOS绘图3D图形库[关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我正在搜索一个可以帮助我绘制 3D 图表的库 我想要类似的东西这一页 http www math uri edu bkaskosz fla
  • iOS 有 INTERNET 权限吗?

    我在 iOS 设备上的 flutter dio 包上遇到了一个奇怪的问题 我编写了一个向 url 发送 GET 请求的应用程序 Android 上一切正常 但 iOS 上的请求似乎无法通过 没有发生任何错误 什么也没有 我在 Android
  • 如何显示接下来的三个图像单击加载更多按钮

    我需要一个加载更多按钮来显示图像 页面加载时 我显示 3 个图像 单击 加载更多 按钮后 接下来的 3 个图像将显示在屏幕上 我尝试了下面的代码 但它不起作用 你能帮我解决这个问题吗 function item slice 0 2 show
  • 如何将设备上未保存的图片上传到dropbox帐户?(IOS)

    Dropbox RestClient 仅保存文件 所以我想先将图像保存在本地文件夹中 然后上传它 结果它保存了文件 但它已损坏 NSString localPath NSBundle mainBundle pathForResource I
  • Swift 单元测试 - 如何断言 CGColor 是它应该的样子?

    使用 Xcode V7 2 尝试进行单元测试 需要验证是否已设置正确的颜色 并收到以下消息 Cannot invoke XCTAssertEqual with an argument list of type CGColor CGColor
  • 将 NSFetchedResultsController 添加到项目后出现问题

    我设置 CoreData 时没有NSFetchedResultsController一切都保存得很好 切换到之后NSFetchedResultsController 我在尝试保存图像时遇到奇怪的错误 这是我用来保存图像的代码 void sa
  • Swift - 保存在 TableView 中选择的复选标记

    我对 Swift 相当陌生 并且在 TableView 多重选择方面遇到问题 我有多个选择 可以用复选标记进行检查 类似于待办事项列表 当我检查项目时 我希望能够返回 ListView 并保存我的选择 我假设将其保持在已保存状态的代码将位于
  • 如何将MathJax公式转换为img

    Mathjax 现在在我的项目中运行良好 但有一个问题 有没有办法将MathJax的公式 纯html和css 转换成img文件 我可以保存 MathJax 可以配置为生成 SVG 看http docs mathjax org en late
  • 为什么这些内联块元素会产生额外的宽度?

    这是这个问题的后续内容 仅使用 css 自动调整图像下的文本 https stackoverflow com questions 34185547 autofit text under image with only css 为什么这段代码
  • 将 html 文本框的值分配给 div 的标题

    line 1

随机推荐