当用户滚动到文档末尾时,我想解锁按钮。 我创建 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
}
}
据我所知,
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
}
}