TL;DR
I will explain about that.
Click here for the source> https://github.com/dropcontrol/PDFViewer
struct ContentView: View {
@ObservedObject var pdfInfo: PDFInfo = PDFInfo()
var body: some View {
VStack {
ShowPDFView(pdfInfo: pdfInfo)
PdfInfoView(pdfInfo: pdfInfo)
.padding()
}.onAppear(){
pdfInfo.addObserver()
}
}
}
The view that becomes the parent calls two views. One is ShowPDFView ()
, which is the viewer part of the PDF, and the other is PdfInfoView ()
, which displays the page number and TOP button below it. So I'm passing pdfInfo: pdfInfo
there, but it's on the View
@ObservedObject var pdfInfo: PDFInfo = PDFInfo()
In the part of, @ObservedObject
creates an instance ofPDFInfo ()
, which is ObservableObject
. And that PDFInfo ()
is ...
class PDFInfo: ObservableObject {
@Published var pageNo: Int = 1
@Published var pdfView: PDFView = PDFView()
@Published var stateTopButton: Bool = false
func addObserver() {
NotificationCenter.default.addObserver(self, selector: #selector(self.pageChanged(_:)), name: Notification.Name.PDFViewPageChanged, object: nil)
}
@objc func pageChanged(_ notification: Notification) {
pageNo = pdfView.currentPage!.pageRef!.pageNumber
stateTopButton = pdfView.canGoToFirstPage
print(self.pageNo)
print("page is changed")
}
}
It looks like this. @Publised
creates variables such as pageNo
, pdfView
, and stateTopButton
. Below that, we define a function of func addObserver () {}
that registers with the Notification Center, and a function of @objc func pageChanged (_ notification: Notification) {}
that is executed when notification is received. Among them are the page number and canGoToFirstPage
to determine if it is the top page of the PDF.
So, in this, it is necessary to display PDF,
@Published var pdfView: PDFView = PDFView()
I am making. So, it is initialized with the previous @ ObservedObject
. Because I want to reuse pdfInfo
in otherView
s, I pass it to the View
that is reading pdfInfo
.
Since PdfInfoView
is in the UI, I think you can understand it by reading the source, so I will omit it and explain ShowPDFView
. Here it looks like this:
struct ShowPDFView: View {
@ObservedObject var pdfInfo: PDFInfo
var body: some View {
PDFViewer(pdfInfo: pdfInfo)
}
}
The parent has passed pdfInfo
to the @ ObservedObject var pdfInfo: PDFInfo
prepared here. I don't see many samples that pass an instance from the parent even if I investigate the case of reusing the instance with @ ObservedObject
, but if I do not do this, I can not refer to the variable set in the previous ObservableObject
.
So, here, PDFViewer (pdfInfo: pdfInfo)
is used to display the actual PDF.
Regarding PDF settings, the writing method with UIViewController etc. is almost the same, but
struct PDFViewer: UIViewRepresentable {
@ObservedObject var pdfInfo: PDFInfo
let url: URL = Bundle.main.url(forResource: "Oz was Wizard - Original Soundtrack", withExtension: "pdf")!
func makeUIView(context: UIViewRepresentableContext<PDFViewer>) -> PDFViewer.UIViewType {
<PDF settings here>
}
func updateUIView(_ uiView: UIView, context: UIViewRepresentableContext<PDFViewer>) {
}
}
It is implemented using UIViewRepresentable
in the form of.
reference:
When using UIKit, it seems that you should write it in the same way. Please refer to the source and other resources for PDF settings.
I wanted to disable the PDF scaling feature, but this isn't functionally implemented in PDFKit, so I'm still looking into it, but I'd be happy if anyone could tell me how to do it.
Recommended Posts