SwiftUI中PDFView获取当前页码及绑定UI更新异常问题
问题:PDFKit滑动翻页时无法同步更新SwiftUI中的当前页码显示
我正在使用PDFKit开发PDF阅读器应用,已通过pdfView.usePageViewController(true)启用原生滑动翻页功能,但无法获取并同步当前页码到SwiftUI界面。目前可以通过pdfView.document?.pageCount获取总页数,也能通过按钮翻页手动计数,但希望保留原生滑动体验。
按照建议添加Coordinator类后,控制台能打印正确的页码变化,但通过Binding将currentPage传递给SwiftUI时,界面上的页码不更新,同时滑动翻页仅会重复显示前两页。
初始代码
ContentView
struct ContentView: View { let url = Bundle.main.url(forResource: "file", withExtension: "pdf") var body: some View { VStack{ PDFKitRepresentedView(data: try! Data(contentsOf: url!)) } } } struct ContentView_Previews: PreviewProvider { static var previews: some View { ContentView() } }
PDFKitRepresentedView
import PDFKit import SwiftUI struct PDFKitRepresentedView: UIViewRepresentable { typealias UIViewType = PDFView let data: Data func makeUIView(context _: UIViewRepresentableContext<PDFKitRepresentedView>) -> UIViewType { // Create a `PDFView` and set its `PDFDocument`. let pdfView = PDFView(frame: CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height)) pdfView.document = PDFDocument(data: data) pdfView.backgroundColor = UIColor.red pdfView.displayMode = .singlePage pdfView.displayDirection = .horizontal pdfView.usePageViewController(true) pdfView.maxScaleFactor = pdfView.scaleFactorForSizeToFit pdfView.minScaleFactor = pdfView.scaleFactorForSizeToFit pdfView.autoScales = true return pdfView } func updateUIView(_ pdfView: UIViewType, context _: UIViewRepresentableContext<PDFKitRepresentedView>) { pdfView.document = PDFDocument(data: data) } }
更新后的代码
ContentView
struct ContentView: View { @State var currentPage = -1 @State var totalPages :Int? let url = Bundle.main.url(forResource: "file", withExtension: "pdf") var body: some View { VStack{ HStack{ Text("\(currentPage)/") Text("\(totalPages ?? 0)") } if let url = url { PDFKitRepresentedView(data:try! Data(contentsOf: url),totalPages: $totalPages,currentPage: $currentPage) } } } }
PDFKitRepresentedView
struct PDFKitRepresentedView: UIViewRepresentable { typealias UIViewType = PDFView let data: Data @Binding var totalPages:Int? @Binding var currentPage :Int let pdfView = PDFView(frame: CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height)) func makeUIView(context: Context) -> UIViewType { pdfView.document = PDFDocument(data: data) pdfView.backgroundColor = UIColor.red pdfView.displayMode = .singlePage pdfView.displayDirection = .horizontal pdfView.usePageViewController(true) pdfView.maxScaleFactor = pdfView.scaleFactorForSizeToFit pdfView.minScaleFactor = pdfView.scaleFactorForSizeToFit pdfView.autoScales = true pdfView.delegate = context.coordinator return pdfView } func updateUIView(_ pdfView: UIViewType, context _: Context) { pdfView.document = PDFDocument(data: data) DispatchQueue.main.async { totalPages = pdfView.document?.pageCount } } func makeCoordinator() -> Coordinator { return Coordinator(self, cp: $currentPage) } class Coordinator: NSObject, PDFViewDelegate { var parent: PDFKitRepresentedView @Binding var currentPage :Int init(_ parent: PDFKitRepresentedView,cp:Binding<Int>) { self.parent = parent _currentPage = cp super.init() NotificationCenter.default.addObserver(self, selector: #selector(pageChangeHandler(_:)), name: .PDFViewPageChanged, object: nil) } @objc func pageChangeHandler(_ notification: Notification) { if let thePage = parent.pdfView.currentPage, let ndx = parent.pdfView.document?.index(for: thePage), currentPage != ndx { DispatchQueue.main.async { self.currentPage = ndx } print("--------> currentPageIndex: \(ndx) ") } } } }
内容的提问来源于stack exchange,提问作者Iftikhar Hussain
相关产品推荐
相关产品推荐

