Q: How to restore last position within document using PDFView and SwiftUI?

I thought about posting this question over at Stack Overflow (and I still may), but the thought of getting a bunch of condescending answers led me to try this first.

There’s not a lot of information out there about integrating PDFKit and SwiftUI. Here’s what I need to do:

  • Wrap PDFView for SwiftUI using UIViewRepresentable and display a PDF that is stored as a binary blob in a Core Data entity (check!).
  • When the user stops viewing the PDF (i.e. when the PDFView disappears), I need to store the scale factor, current page index, and a CGRect representing the section of the page the user is looking at (a CGRect seems easier to save in Core Data than whatever a PDFDestination is). All of those properties can be obtained from the PDFView object, and I’d like to save them in Core Data in the same entity as the PDF data.
  • Next time the user views the PDF, restore it to the same location the user viewed last, at the same zoom level.

Here’s where I’m confused:

  1. I can set the PDFView’s scaleFactor in the “makeUIView” function required for all UIViewRepresentable-conforming structs. How do I set it to display a specific page before it appears? Using the “go(to: PDFPage)” function before returning the PDFView doesn’t seem to work. Putting it in the “update” function would cause it to jump back to the same page every time the view updated.
  2. How can I access the PDFView’s scaleFactor and current page index and save it in Core Data before the view disappears? Can I access the managed object context environment variable in my UIViewRepresentable struct somewhere, or within a Coordinator or something (I don’t currently have a Coordinator set up)?

I just can’t seem to figure out what to do here. There are so many options for communicating at various times: Notifications, bindings, ObservableObjects, the dismantleUIView function, onAppear/onDisappear modifiers… I’m suddenly lost as to how to approach this.

If you think you can help: comments are open! I hope to update this post with a working solution soon.


Inktober 2019, Day 31, “Ripe”

And that’s a wrap for Inktober! It was a fun addition to my daily schedule and I’m pleasantly surprised that I managed to complete it without missing a day. Now, back to coding! 🙂


Inktober 2019, Day 25, “Tasty”

This is a sign for a restaurant in Lincoln that opened in 1948 and closed in 2013. I never ate there, but I’ve heard that it was much loved.


Inktober 2019, Day 23, “Ancient”

This isn’t something that’s actually ancient, just something that feels ancient: a micro cassette containing an audio recording of me talking about my life when I was 8 years old.


Inktober 2019, Day 19, “Sling”

I’m not particularly good at portraits, but the only thing that came to mind when I saw the word “sling” was Charlie’s little friend Amy, who recently broke her arm on the playground. I traced the outline of her body and her eyes, nose, and mouth (because I knew I’d mess up the proportions).