我正在尝试创建一个EPUB阅读器。由于EPUB中的章节被表示为没有分页符的完整HTML文件,我将在WKWebView
中一次显示一页,加载loadHTMLString
字符串。然后,当用户滑动到UIPageViewController
的下一页时,我将创建一个新的WKWebView
,并使用setContentOffset
方法向下滚动一个页面。但是,setContentOffset
方法对显示的内容没有影响。tldr -如何判断这个setContentOffset
方法何时可以安全调用?
下面是我的页面视图控制器:
class MyPageViewController: UIPageViewController, UIPageViewControllerDelegate, UIPageViewControllerDataSource {
var page = 0
override func viewDidLoad() {
super.viewDidLoad()
dataSource = self
delegate = self
setViewControllers([Page(page: 0)], direction: .forward, animated: false, completion: nil)
}
func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? {
return nil
}
func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? {
return Page(page: page + 1)
}
func pageViewController(_ pageViewController: UIPageViewController, didFinishAnimating finished: Bool, previousViewControllers: [UIViewController], transitionCompleted completed: Bool) {
if completed {
page += 1
}
}
}
下面是我的Page
类:
class Page: UIViewController, WKNavigationDelegate, WKUIDelegate {
var page: Int
var webView: WKWebView!
let testString = "<h1>00000000000000000000000000000000000000000000000000</h1><br><h1>11111111111111111111111111111111111111111111111111</h1><br><h1>22222222222222222222222222222222222222222222222222</h1><br><h1>33333333333333333333333333333333333333333333333333</h1><br><h1>44444444444444444444444444444444444444444444444444</h1><br><h1>55555555555555555555555555555555555555555555555555</h1><br><h1>66666666666666666666666666666666666666666666666666</h1><br><h1>77777777777777777777777777777777777777777777777777</h1><br><h1>88888888888888888888888888888888888888888888888888</h1><br><h1>99999999999999999999999999999999999999999999999999</h1>"
init(page: Int) {
self.page = page
super.init(nibName: nil, bundle: nil)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func viewDidLoad() {
super.viewDidLoad()
webView = WKWebView(frame: view.bounds)
webView.navigationDelegate = self
view.addSubview(webView)
load()
}
func load() {
webView.loadHTMLString(testString, baseURL: nil)
}
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
self.scroll()
}
func scroll() {
let scrollPoint = CGPoint(x: 0, y: 100 * CGFloat(page))
webView.scrollView.setContentOffset(scrollPoint, animated: false)
}
}
我希望滚动是即时的,这样用户就不会知道它在滚动,因此使用了animated: false
。然而,这根本不会以任何方式改变视图。如果我使用animated: true
,它可以正常工作,如果我将self.scroll()
Package 在DispatchQueue.main.asyncAfter(deadline: .now() + 0.1)
中,它也可以正常工作。但是如果我这样做的话,用户可能会看到一个不和谐的滚动。我试过调用.setNeedsLayout()
和.layoutIfNeeded()
都没有用;景色依旧没有改变。
所以很明显,有些东西还没有准备好滚动webView,即使在调用didFinish
委托方法之后也是如此。我怎么知道这个webView
什么时候可以滚动?或者还有其他原因导致animated: false
不工作?
2条答案
按热度按时间jm81lzqq1#
在研究了这个问题之后,我得出了与https://stackoverflow.com/a/76145772/8010366相似的结论。初始滚动似乎存在问题。
但是,如果您仍然需要在没有动画的情况下手动滚动,则可以使用以下低级代码:
这将执行JavaScript代码来滚动HTML文档。此外,您应该添加更多内容以启用滚动。
希望这有帮助!
参考文献:
vatpfxk52#
我没有一个实际的答案,但这里有一些更多的信息
为了弄清楚这是怎么回事,我让de Page类成为webiew scrollView的委托。当这样做时,你可以看到在delegates
scrollViewDidScroll
事件中放置print时发生了一些奇怪的事情:最初,偏移量 * 确实 * 被设置为100,但随后发生了一些奇怪的事情,偏移量在最终回到0之前到处都是。
如果你把animated设置为
true
,也会发生类似的事情,但是因为它是动画的,所以它会自动修复。我不知道是什么原因造成的,也没有时间进一步调查。我最好的建议是接受动画卷轴或推迟它现在。如果你真的不想让别人看到你的行为,也许你可以把webView隐藏在一个正在加载的视图后面,直到所有的东西都被加载了。