PDF를 표시하는 뷰어 앱을 만들었습니다.

4722 단어 iOSSwiftSwiftUIPDFKit

TL;DR


  • PDFKit 샘플을 SwiftUI에서 만들었습니다
  • 페이지를 넘길 때마다 현재 표시된 PDF의 페이지 번호를 가져옵니다
  • 에서 NotificatonCenter에 addObserve하여 PDFView에서 페이지 번호를 가져옵니다
  • 에서, 그 경우 ViewController 시대라면 ViewDidLoad등으로 등록하거나 할 수 있습니다만, 어떻게 하면 좋을까,,,

  • 라고 하는 근처를 해설합니다.

    데모





    소스는 이쪽> htps : // 기주 b. 이 m / d 로 p 콘 t 로 l / PDF ゔ ぃ

    View 해설에서


    struct ContentView: View {
        @ObservedObject var pdfInfo: PDFInfo = PDFInfo()
    
        var body: some View {
            VStack {
                ShowPDFView(pdfInfo: pdfInfo)
                PdfInfoView(pdfInfo: pdfInfo)
                .padding()
            }.onAppear(){
                pdfInfo.addObserver()
            }
    
        }
    }
    

    가장 부모가 되는 View에서는 두 개의 View를 부르고 있습니다. 하나는 PDF의 뷰어 부분인 ShowPDFView() 이고 다른 하나는 그 아래에 페이지 번호와 TOP 버튼을 표시하고 있다 PdfInfoView() 입니다. 그래서 거기에서 pdfInfo: pdfInfo를 전달하지만 View 위에 있습니다.
    @ObservedObject var pdfInfo: PDFInfo = PDFInfo()
    

    의 부분에서 @ObservedObject 에서 ObservableObjectPDFInfo() 의 인스턴스를 만들고 있습니다. 그래서 PDFInfo()
    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")
        }
    }
    

    이런 느낌이 되고 있습니다. @Publised에서는 pageNo, pdfView, stateTopButton 등의 변수를 만들고 있습니다. 그 아래에서는 NotificasionCenter에 등록func addObserver(){}을, notification을 받으면 실행되는@objc func pageChanged(_ notification: Notification) {}의 함수를 정의하고 있습니다. 그 중에서는 페이지 번호와 PDF의 톱 페이지인가 어떤가를 판단한다 canGoToFirstPage입니다.

    그래서이 중 PDF를 표시하는 데 필요한,
    @Published var pdfView: PDFView = PDFView()
    

    을 만들고 있습니다. 그래서 앞의 @ObservedObject로 초기화하고 있습니다. pdfInfo를 다른 View에서도 사용하고 싶기 때문에 pdfInfo를 읽고있는 View에 전달합니다.

    기타 View 정보


    PdfInfoView 는 UI의 장소이므로 소스 읽으면 알 수 있다고 생각하기 때문에 할애하고, ShowPDFView 를 해설합니다. 여기에서는 다음과 같은 느낌입니다.
    struct ShowPDFView: View {
        @ObservedObject var pdfInfo: PDFInfo
    
        var body: some View {
            PDFViewer(pdfInfo: pdfInfo)
        }
    }
    

    여기 @ObservedObject var pdfInfo: PDFInfo에 부모로부터 pdfInfo를 전달합니다. @ObservedObject 에서 인스턴스를 사용하는 경우를 조사해도 부모로부터 인스턴스를 건네준다고 하는 샘플은 별로 보이지 않습니다만, 이것으로 하지 않으면 앞의 ObservableObject로 설정한 변수를 참조할 수 없습니다.

    그래서 여기에서는 PDFViewer(pdfInfo: pdfInfo)에서 실제 PDF를 표시하고 있습니다.

    PDFViewer() 정보



    PDF의 설정에 대해서는 UIViewController등에서의 쓰는 방법은 거의 함께입니다만,
    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の設定>
        }
    
        func updateUIView(_ uiView: UIView, context: UIViewRepresentableContext<PDFViewer>) {
        }
    
    }
    

    라고 하는 형태로 UIViewRepresentable (을)를 사용해 실장하고 있습니다.
    참조:
    * htps : //로 ゔぇぺぺr. 아 ぇ. 코 m / 도쿠 멘 타치 온 / 수프 f 츠 / 우이 ゔ 에어 w
    * htps : // 이 m/k_아키키/있어 ms/448fd0bd6f51500d13b1

    UIKit을 사용하기 위해서는 이것과 같은 글을 쓰면 좋을 것 같습니다.
    PDF의 설정 주위는 소스나 다른 리소스를 참고로 받으면.

    이 샘플에서 할 수없는 일



    PDF를 확대/축소하는 기능을 무효로 하고 싶었습니다만, 이것은 PDFKit에서는 기능적으로는 실장되어 있지 않기 때문에, 아직 조사하고 있습니다만 하는 방법을 아는 분 가르쳐 주시면 기쁩니다.

    좋은 웹페이지 즐겨찾기