fix(reader): stabilize pagination display and page curl reuse
This commit is contained in:
@@ -624,19 +624,31 @@ public class RDReaderView: UIView {
|
||||
/// 获取用于显示的页面视图
|
||||
/// 优先从缓存中获取,其次从预加载缓存中获取,最后新建
|
||||
private func pageViewForDisplay(pageNum: Int) -> UIView {
|
||||
if let cached = pageCurlCachedViews[pageNum] {
|
||||
return cached
|
||||
}
|
||||
if let preloaded = preloadedPageViews.removeValue(forKey: pageNum) {
|
||||
preloaded.removeFromSuperview()
|
||||
pageCurlCachedViews[pageNum] = preloaded
|
||||
return preloaded
|
||||
}
|
||||
let view = dataSource?.pageContentView(readerView: self, pageNum: pageNum, containerView: nil) ?? UIView()
|
||||
let reusableView = detachedReusablePageView(for: pageNum)
|
||||
let view = dataSource?.pageContentView(readerView: self, pageNum: pageNum, containerView: reusableView)
|
||||
?? reusableView
|
||||
?? UIView()
|
||||
pageCurlCachedViews[pageNum] = view
|
||||
return view
|
||||
}
|
||||
|
||||
/// 返回可安全复用的 page view。
|
||||
/// 只有已经脱离视图层级的 view 才能复用,避免 pageCurl 转场期间同一个 UIView
|
||||
/// 被多个 child controller 争用,从而导致前一个页面瞬时空白。
|
||||
private func detachedReusablePageView(for pageNum: Int) -> UIView? {
|
||||
if let preloaded = preloadedPageViews.removeValue(forKey: pageNum) {
|
||||
preloaded.removeFromSuperview()
|
||||
return preloaded
|
||||
}
|
||||
|
||||
guard let cached = pageCurlCachedViews[pageNum], cached.superview == nil else {
|
||||
return nil
|
||||
}
|
||||
|
||||
pageCurlCachedViews.removeValue(forKey: pageNum)
|
||||
return cached
|
||||
}
|
||||
|
||||
/// 裁剪缓存,只保留指定页码集合中的页面
|
||||
/// 不在保留集合中的页面会被从视图层级中移除
|
||||
private func trimCachedPageViews(keeping pageNumbers: Set<Int>) {
|
||||
@@ -705,7 +717,7 @@ public class RDReaderView: UIView {
|
||||
preloadHostView.frame = bounds
|
||||
|
||||
for targetPage in targets {
|
||||
let existing = preloadedPageViews[targetPage] ?? pageCurlCachedViews.removeValue(forKey: targetPage)
|
||||
let existing = detachedReusablePageView(for: targetPage)
|
||||
let contentView = dataSource?.pageContentView(readerView: self, pageNum: targetPage, containerView: existing) ?? existing ?? UIView()
|
||||
preloadedPageViews[targetPage] = contentView
|
||||
if contentView.superview !== preloadHostView {
|
||||
|
||||
Reference in New Issue
Block a user