如何在 PDFKit 中跟踪 onReachBottom 事件

问题描述 投票:0回答:1

当用户滚动到文档末尾时,我想解锁按钮。 我创建 PDFView 像:

import PDFKit
import SwiftUI

struct PDFDocumentView: UIViewRepresentable {

    private var url: URL?
    private let pdfDocumentDelegate: PdfDocumentDelegate = PdfDocumentDelegate()

    init(url: URL) {
        self.url = url
    }

    func makeUIView(context: Context) -> PDFView {
        let pdfView = PDFView()
        if let url {
            pdfView.document = PDFDocument(url: url)
            pdfView.autoScales = true
            pdfView.setNeedsLayout()
            pdfView.layoutIfNeeded()
            pdfView.maxScaleFactor = 3.0
            pdfView.minScaleFactor = pdfView.scaleFactorForSizeToFit
        }
        return pdfView
    }
}
swift pdfkit
1个回答
1
投票

据我所知,

PDFView
没有公共API来执行此操作。

如果您可以控制所显示的 PDF 文件,则可以在文档末尾添加一个非常小的(就页面高度而言)页面,观察

PDFViewVisiblePagesChanged
通知,并检查
pdfView.visiblePages.last
是最后一个
pdfView.document
页。

否则,您可以尝试在

UIScrollView
的视图层次结构中找到
PDFView
,尽管这没有记录。

使用此滚动视图,您可以根据您的偏好实现其委托方法

scrollViewDidScroll
scrollViewDidEndDecelerating
(请参阅这个答案),或者使用 KVO 来观察
contentOffset
的更改(请参阅这个答案) .

在能够检测到滚动后,您可以通过检查

contentOffset
来检查滚动视图是否位于底部(请参阅这个答案)。

这是一个例子:

var pdfView: PDFView!

override func viewDidLoad() {
    pdfView = PDFView(...)
    // configure pdfView however you want...
    pdfView.document = ...
    // on iOS 17 at least, subviews[0] is the scroll view
    // to be more future proof, consider searching recursively
    scrollViewDelegate = (pdfView.subviews[0] as? UIScrollView)?.delegate
    (pdfView.subviews[0] as? UIScrollView)?.delegate = self
}

var scrollViewDelegate: UIScrollViewDelegate?

func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
    scrollViewDelegate?.scrollViewDidEndDecelerating?(scrollView)
    if scrollView.isAtBottom {
        print("Bottom")
    }
}

// you should implement all the other UIScrollViewDelegate methods like this,
// in case PDFView needs them
func scrollViewDidScroll(_ scrollView: UIScrollView) {
    scrollViewDelegate?.scrollViewDidScroll?(scrollView)
}

func scrollViewDidZoom(_ scrollView: UIScrollView) {
    scrollViewDelegate?.scrollViewDidZoom?(scrollView)
}

UIScrollView.isAtBottom
来自链接的答案

extension UIScrollView {
    var isAtBottom: Bool {
        return contentOffset.y >= verticalOffsetForBottom
    }
    
    var verticalOffsetForBottom: CGFloat {
        let scrollViewHeight = bounds.height
        let scrollContentSizeHeight = contentSize.height
        let bottomInset = contentInset.bottom
        let scrollViewBottomOffset = scrollContentSizeHeight + bottomInset - scrollViewHeight
        return scrollViewBottomOffset
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.