1

I'm having great difficulty working out how to implement a PDFView using UIViewRepresentable.

I understand that I can get variables from SwiftUI -> UIKit via a simple Binding.

I understand that I need to use a Coordinator to detect PDFView Notifications such as PDFViewPageChanged etc and then pass data back with the Binding.

I cant find an example of how you can use Coordinator to pick up notifications. Any help would be greatly appretiated.

Thanks

EDIT

What I've tried - unfortuantly I never recieve a notification

func makeUIView(context: Context) -> PDFView {
    let pdfView = PDFView()
    pdfView.document = pdfDocument
    pdfView.autoScales = true
    
    NotificationCenter.default.publisher(for: .PDFViewPageChanged)
        .map {$0.object as? PDFView}
        .sink { (view) in
            print("notification received")
        }
                
    return pdfView
}
swift--help
  • 637
  • 5
  • 15

1 Answers1

2

Something like this:

struct SPDFView: UIViewRepresentable {
  let document: PDFDocument
  @Binding var selection: String?
  
  func makeUIView(context: Context) -> PDFView {
    let view = PDFView()
    view.document = document
    NotificationCenter.default.publisher(for: .PDFViewSelectionChanged)
      .map { $0.object as? PDFView }
      .sink { (view) in
        // or do something else
        self.selection = view?.currentSelection?.string
      }
      .store(in: &cancellables)

// or, if you don't want to use Combine:
// NotificationCenter.default.addObserver(forName: .PDFViewSelectionChanged, object: nil, queue: nil) { (notification) in
//      guard let pdfView = notification.object as? PDFView else { return }
//      self.selection = pdfView.currentSelection?.string
//    }

    return view
  }

  func updateUIView(_ uiView: PDFView, context: Context) {}
}
Cenk Bilgen
  • 1,330
  • 9
  • 8
  • Thanks for getting back to me, I'm afraid I'm not getting any notifications with that method. I've added the code I've tried to my original comment. – swift--help Dec 22 '20 at 09:37
  • 1
    The `.store` can't be left out after the .sink (you should have got a compiler warning). Otherwise, if not stored, the whole handler will be released at the end of the makeUIView function and there will be nothing to handle the notification. If you don't want to use the Notification Publishers, the closure based handlers will work just as well (I'll add that to my answer later). Another unrelated point is keep in mind there are notifications when the current page changes and when the current _visible_ pages change. Usually the second is what you want. – Cenk Bilgen Dec 22 '20 at 15:19
  • So silly of me. Thanks very much for your help! – swift--help Dec 22 '20 at 16:47