Display and manipulate PDF documents in your applications using PDFKit.

Posts under PDFKit tag

34 Posts

Post

Replies

Boosts

Views

Activity

PDFKit Page Rerender
I'm experiencing an issue with PDFKit where page.removeAnnotation(annotation) successfully removes the annotation from the page's data structure, but the PDFView no longer updates automatically to reflect the change visually. Issue Details: The annotation is removed (verified by checking page.annotations.count) The PDFView display doesn't refresh to show the removal This code was working correctly before and suddenly stopped working No code changes were made on my end
3
0
442
13h
PDFKit Sizes increases
Hey there, I have a slight problem which is also known on the web, but I couldn't find any answers... My iOS App is working with documents like pdf and images. It is made to handle invoices and upload them to an external service. The app's job is to compress those pdfs and images. Sadly the PDFKit's PDFDocument increases its size just after importing it with pdfDocument = PDFDocument(url: url) and later exporting it to an pdf file again with data = pdf.dataRepresentation() without ever modifying it. It increases by server KB after each export. Do you have any alternatives to the renderer dataRepresentation() or a general PDFKit alternative Thanks
1
1
489
1w
PDFKit doesn't return the correct page
Hello, We are experiencing on some occasions a wrong behavior with PDFDocument method: func page(at index: Int) -> PDFPage? With certain PDF files, this method returns the wrong PDFPage. This occurs on iOS 18.3, 18.5 and 18.6.2 (an maybe on other versions). Try this PDF for instance (page 81 is returned when index = 2): https://drive.google.com/open?id=1MHm2wjfsbWB8OiRmARUMmvODYxp4DIqP&usp=drive_fs Also, I mention that this doesn't occur systematically with this PDF. When making a copy of this file we don't observe the issue. Could this be linked some kind of internal cache issue ?
0
0
72
2w
PDF Page Content Swapping on iOS 26
Dear Apple Developer Team, On iOS 26, the contents of PDF pages appear to be swapped. Could you please advise if there is a workaround or a planned fix for this issue? Steps to Reproduce: Download the attached PDF on iOS 26. Open the PDF in the Files app. Tap the PDF to view it in Quick Look. Navigate to page 5. Expected Result: The page number displayed at the bottom should be 5. Actual Result: The page number displayed at the bottom is 4. Issue: This is not limited to page 5—multiple page contents appear to be swapped. I have also submitted feedback via Feedback Assistant (FB20743531) on October 20. Best regards, Yoshihito Suezawa
3
0
163
Nov ’25
Can't remove annotations from PdfView
Hi everyone, I faced an issue that on IOS 26 removeAnnotation method doesn't remove annotation. This code worked on previous versions (IOS 18, 17) but suddenly stopped working on IOS 26. Has anyone faced this issue? guard let document = await pdfView.document else { return } for pageIndex in 0..<document.pageCount { guard let page = document.page(at: pageIndex) else { continue } let annotations = page.annotations for annotation in annotations { page.removeAnnotation(annotation) } }
1
0
193
Oct ’25
How do I flatten a PDF using Shortcuts or Automator?
Looking for any method to quickly flatten a PDF without opening Preview and without installing 3 party software. Any ideas? Save as PDF in Preview works, but I don't want to have to open Preview each time I need to do this. The Create PDF action which appears in Finder when you select 2 or more PDFs flattens PDFs, but it requires me to select 2 or more files, and I generally don't want to combine PDFs--I simply wish to flatten a PDF. Most Automator and Shortcuts options I am aware of do not flatten PDFs, and in some cases, strip out form field data from PDFs.
7
0
285
Oct ’25
PDFView Crash After Find Changing current selection and calling -scrollSelectionToVisible: on macOS Tahoe
Getting this crash after I do this in PDFKit a lot: PDFSelection *nextSelect = [self.pdfView.document findString:currentSearchString fromSelection:currentSelction withOptions:NSCaseInsensitiveSearch]; if (nextSelect != nil) { self.pdfView.currentSelection = nextSelect; [self.pdfView scrollSelectionToVisible:nil]; } Which often leads to: 0 CoreFoundation 0x000000019ced4770 __exceptionPreprocess + 176 1 libobjc.A.dylib 0x000000019c9b2418 objc_exception_throw + 88 2 CoreFoundation 0x000000019cfffe10 -[__NSPlaceholderDictionary initWithObjects:forKeys:count:] + 724 3 CoreFoundation 0x000000019cfa1ae4 +[NSDictionary dictionaryWithObjects:forKeys:count:] + 52 4 PDFKit 0x00000001cb56e0fc -[PDFView _axPostPageChangeNotification:] + 348 5 Foundation 0x000000019e6a25e4 __NSFireDelayedPerform + 372 6 CoreFoundation 0x000000019ce92290 __CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__ + 32 7 CoreFoundation 0x000000019ce91f50 __CFRunLoopDoTimer +
3
0
140
Oct ’25
PDFKit Zoom Performance Issue with Many Annotations
Hello, I’m using PDFKit to display PDFs with a large number of annotations. However, when there are many annotations, I’m experiencing serious performance issues while zooming in/out with PDFView. • During pinch zoom, it seems like continuous re-rendering occurs. • Memory usage spikes dramatically while zooming, then drops back down repeatedly. • As a result, zooming feels laggy and not smooth. What I’d like to achieve is the following: 1. Prevent unnecessary re-rendering while zooming is in progress. 2. Trigger a single re-render only once the zoom gesture ends (e.g., in scrollViewDidEndZooming). 3. At the very least, avoid the memory spikes during zoom. Is there any way to control how annotations are re-drawn during zooming in PDFKit, or to throttle/debounce rendering so it happens only after the gesture completes? I’d really appreciate any advice from others who have encountered similar issues, or guidance from Apple on the recommended approach. Thanks in advance!
Topic: UI Frameworks SubTopic: UIKit Tags:
0
0
85
Oct ’25
PDFKit – How can I draw annotations behind text in PDFView?
Hi, I’m currently working with PDFKit and using PDFView to display documents. I’m adding free-drawing content as annotations, but I’ve noticed that these annotations are always rendered on top of the text, which ends up covering the text and making it hard to read. What I would like to do is render these drawing annotations behind the text layer, so that the document text remains visible above the drawing. Has anyone found a way to achieve this, or is there a recommended approach for controlling the annotation rendering order in PDFKit? Thanks in advance!
1
0
71
Sep ’25
PDFKit PdfView Black Boxes sometimes
Hi! I'm using PDFKits PdfView to display a PDF file and after several page changes, the background turns black, suddenly (like a big black rectangle). The error occurs in the Books App on the iPad as well and looks similiar to this issue: https://discussions.apple.com/thread/8627073?sortBy=rank Anyone got a solution for this?
1
0
188
Sep ’25
Copy file in application document file to user Documents file
I ave an application that makes use of charts. I would like to have a button for the user to save the chart as a PDF. I tried to have the button save the PDF to the user's document directory directly. That attempt failed. But I was able to save the PDF to the application sandboxed documents directory. The question is how to programmatically move that file from the application documents folder to the user's general documents folder. So far I have not been able to find a method that will move the PDF file. Any ideas?
2
0
313
Sep ’25
Unexpected lines appear in PDFView on visionOS 26 beta
I’m attempting to display a PDF file in a visionOS application using the PDFView in PDFKit. When running on device with visionOS 26, a horizontal solid line appears on some pages, while on other pages, both a horizontal and vertical solid line appear. These lines do not appear in Xcode preview canvas (macOS, visionOS) on device running visionOS 2.5 on Mac running macOS 15.6 I thought that this could possibly be the page breaks, but setting displaysPageBreaks = false did not appear to be effective. Are there any other settings that could be causing the lines to display? Code Example struct ContentView: View { @State var pdf: PDFDocument? = nil var body: some View { PDFViewWrapper(pdf: pdf) .padding() } } #Preview(windowStyle: .automatic) { ContentView(pdf: PDFDocument(url: Bundle.main.url(forResource: "SampleApple", withExtension: "pdf")!)) .environment(AppModel()) } struct PDFViewWrapper: UIViewRepresentable { let pdf: PDFDocument? func makeUIView(context: Context) -> PDFView { let view = PDFView() view.document = pdf view.displaysPageBreaks = false return view } func updateUIView(_ uiView: PDFView, context: Context) { uiView.document = pdf } } Tested with Xcode Version 16.4 (16F6) Xcode Version 26.0 beta 5 (17A5295f) visionOS 2.5 visionOS 26 Beta 5 I
2
0
105
Aug ’25
The PKCanvasView Created by PDFPageOverlayViewProvider cannot work normally
By setting the PKCanvasView background color to blue, I can tell that the PKCanvasView for each PDFPage is created normally, but it does not respond to touch. Specifically, whether it is finger or applepencil, all the responses of the page occur from PDFView(such as zoom and scroll), and PKCanvasView can not draw, please how to solve? class PDFAnnotatableViewController: UIViewController, PDFViewDelegate { private let pdfView = PDFView() private var pdfDocument: PDFDocument? let file: FileItem private var userSettings: UserSettings @Binding var selectedPage: Int @Binding var currentMode: Mode @Binding var latestPdfChatResponse: LatestPDFChatResponse @State private var pdfPageCoordinator = PDFPageCoordinator() @ObservedObject var userMessage: ChatMessage init(file: FileItem, userSettings: UserSettings, drawDataList: Binding<[DrawDataItem]>, selectedPage: Binding<Int>, currentMode: Binding<Mode>, latestPdfChatResponse: Binding<LatestPDFChatResponse>, userMessage: ChatMessage) { self.file = file self.userSettings = userSettings self._selectedPage = selectedPage self._currentMode = currentMode self._latestPdfChatResponse = latestPdfChatResponse self.userMessage = userMessage super.init(nibName: nil, bundle: nil) DispatchQueue.global(qos: .userInitiated).async { if let document = PDFDocument(url: file.pdfLocalUrl) { DispatchQueue.main.async { self.pdfDocument = document self.pdfView.document = document self.goToPage(selectedPage: selectedPage.wrappedValue - 1) } } } } required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } override func viewDidLoad() { super.viewDidLoad() setupPDFView() } private func setupPDFView() { pdfView.delegate = self pdfView.autoScales = true pdfView.displayMode = .singlePage pdfView.displayDirection = .vertical pdfView.backgroundColor = .white pdfView.usePageViewController(true) pdfView.displaysPageBreaks = false pdfView.displaysAsBook = false pdfView.minScaleFactor = 0.8 pdfView.maxScaleFactor = 3.5 pdfView.pageOverlayViewProvider = pdfPageCoordinator if let document = pdfDocument { pdfView.document = document goToPage(selectedPage: selectedPage) } pdfView.frame = view.bounds pdfView.autoresizingMask = [.flexibleWidth, .flexibleHeight] view.addSubview(pdfView) NotificationCenter.default.addObserver( self, selector: #selector(handlePageChange), name: .PDFViewPageChanged, object: pdfView ) } // Dealing with page turning @objc private func handlePageChange(notification: Notification) { guard let currentPage = pdfView.currentPage, let document = pdfView.document else { return } let currentPageIndex = document.index(for: currentPage) if currentPageIndex != selectedPage - 1 { DispatchQueue.main.async { self.selectedPage = currentPageIndex + 1 } } } func goToPage(selectedPage: Int) { guard let document = pdfView.document else { return } if let page = document.page(at: selectedPage) { pdfView.go(to: page) } } // Switch function func togglecurrentMode(currentMode: Mode){ DispatchQueue.main.async { if self.currentMode == .none{ self.pdfView.usePageViewController(true) self.pdfView.isUserInteractionEnabled = true } else if self.currentMode == .annotation { if let page = self.pdfView.currentPage { if let canvasView = self.pdfPageCoordinator.getCanvasView(forPage: page) { canvasView.isUserInteractionEnabled = true canvasView.tool = PKInkingTool(.pen, color: .red, width: 20) canvasView.drawingPolicy = .anyInput canvasView.setNeedsDisplay() } } } } } } class MyPDFPage: PDFPage { var drawing: PKDrawing? func setDrawing(_ drawing: PKDrawing) { self.drawing = drawing } func getDrawing() -> PKDrawing? { return self.drawing } } class PDFPageCoordinator: NSObject, PDFPageOverlayViewProvider { var pageToViewMapping = [PDFPage: PKCanvasView]() func pdfView(_ view: PDFView, overlayViewFor page: PDFPage) -> UIView? { var resultView: PKCanvasView? = nil if let overlayView = pageToViewMapping[page] { resultView = overlayView } else { let canvasView = PKCanvasView(frame: view.bounds) canvasView.drawingPolicy = .anyInput canvasView.tool = PKInkingTool(.pen, color: .systemYellow, width: 20) canvasView.backgroundColor = .blue pageToViewMapping[page] = canvasView resultView = canvasView } if let page = page as? MyPDFPage, let drawing = page.drawing { resultView?.drawing = drawing } return resultView } func pdfView(_ pdfView: PDFView, willEndDisplayingOverlayView overlayView: UIView, for page: PDFPage) { guard let overlayView = overlayView as? PKCanvasView, let page = page as? MyPDFPage else { return } page.drawing = overlayView.drawing pageToViewMapping.removeValue(forKey: page) } func savePDFDocument(_ pdfDocument: PDFDocument) -> Data { for i in 0..<pdfDocument.pageCount { if let page = pdfDocument.page(at: i) as? MyPDFPage, let drawing = page.drawing { let newAnnotation = PDFAnnotation(bounds: drawing.bounds, forType: .stamp, withProperties: nil) let codedData = try! NSKeyedArchiver.archivedData(withRootObject: drawing, requiringSecureCoding: true) newAnnotation.setValue(codedData, forAnnotationKey: PDFAnnotationKey(rawValue: "drawingData")) page.addAnnotation(newAnnotation) } } let options = [PDFDocumentWriteOption.burnInAnnotationsOption: true] if let resultData = pdfDocument.dataRepresentation(options: options) { return resultData } return Data() } func getCanvasView(forPage page: PDFPage) -> PKCanvasView? { return pageToViewMapping[page] } } Is there an error in my code? Please tell me how to make PKCanvasView painting normally?
1
0
422
Aug ’25
How to fix the gestureRecognizer over PDFKit breaking the paging in the new ios26 version?
I had project going great, where i needed to do stuff with pdfs, drawing on top them etc. Since apple is all closed sourced i needed to become a bit hacky. Anyways, i have a problem since the new ios 26 update which breaks the behaviour. I simplified the code very much into a demo project, where you can quickly see what's wrong. When swiping left to go to the next page, it does change the page etc in the pdf Document, but visually nothing happens. I am stuck on the first page. I dont know what to do, tried a lot of things, but nothing works. Anyone skilled enough to help me out? import UIKit import PDFKit import SwiftUI class PDFViewController: UIViewController { var pdfView: PDFView! var gestureHandler: GestureHandler! override func viewDidLoad() { super.viewDidLoad() setupPDFView() setupGestureHandler() loadPDF() } private func setupPDFView() { pdfView = PDFView(frame: view.bounds) // Your exact configuration pdfView.autoScales = true pdfView.pageShadowsEnabled = false pdfView.backgroundColor = .white pdfView.displayMode = .singlePage view.addSubview(pdfView) // Setup constraints pdfView.translatesAutoresizingMaskIntoConstraints = false NSLayoutConstraint.activate([ pdfView.topAnchor.constraint(equalTo: view.topAnchor), pdfView.leadingAnchor.constraint(equalTo: view.leadingAnchor), pdfView.trailingAnchor.constraint(equalTo: view.trailingAnchor), pdfView.bottomAnchor.constraint(equalTo: view.bottomAnchor) ]) } private func setupGestureHandler() { gestureHandler = GestureHandler(pdfView: pdfView) gestureHandler.setupSwipeGestures(on: view) } private func loadPDF() { if let path = Bundle.main.path(forResource: "sonate12", ofType: "pdf"), let document = PDFDocument(url: URL(fileURLWithPath: path)) { pdfView.document = document } else { print("Could not find sonate12.pdf in bundle") } } } class GestureHandler { private weak var pdfView: PDFView? init(pdfView: PDFView) { self.pdfView = pdfView } func setupSwipeGestures(on view: UIView) { // Left swipe - go to next page let leftSwipe = UISwipeGestureRecognizer(target: self, action: #selector(handleSwipe(_:))) leftSwipe.direction = .left view.addGestureRecognizer(leftSwipe) // Right swipe - go to previous page let rightSwipe = UISwipeGestureRecognizer(target: self, action: #selector(handleSwipe(_:))) rightSwipe.direction = .right view.addGestureRecognizer(rightSwipe) } @objc private func handleSwipe(_ gesture: UISwipeGestureRecognizer) { guard let pdfView = pdfView, let document = pdfView.document, let currentPage = pdfView.currentPage else { print("🚫 No PDF view, document, or current page available") return } let currentIndex = document.index(for: currentPage) let totalPages = document.pageCount print("📄 Current state: Page \(currentIndex + 1) of \(totalPages)") print("👆 Swipe direction: \(gesture.direction == .left ? "LEFT (next)" : "RIGHT (previous)")") switch gesture.direction { case .left: // Next page guard currentIndex < document.pageCount - 1 else { print("🚫 Already on last page (\(currentIndex + 1)), cannot go forward") return } let nextPage = document.page(at: currentIndex + 1) if let page = nextPage { print("➡️ Going to page \(currentIndex + 2)") pdfView.go(to: page) pdfView.setNeedsDisplay() pdfView.layoutIfNeeded() // Check if navigation actually worked DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) { if let newCurrentPage = pdfView.currentPage { let newIndex = document.index(for: newCurrentPage) print("✅ Navigation result: Now on page \(newIndex + 1)") if newIndex == currentIndex { print("⚠️ WARNING: Page didn't change visually!") } } } } else { print("🚫 Could not get next page object") } case .right: // Previous page guard currentIndex > 0 else { print("🚫 Already on first page (1), cannot go back") return } let previousPage = document.page(at: currentIndex - 1) if let page = previousPage { print("⬅️ Going to page \(currentIndex)") pdfView.go(to: page) pdfView.setNeedsDisplay() pdfView.layoutIfNeeded() let bounds = pdfView.bounds pdfView.bounds = CGRect(x: bounds.origin.x, y: bounds.origin.y, width: bounds.width + 0.01, height: bounds.height) pdfView.bounds = bounds // Check if navigation actually worked DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) { if let newCurrentPage = pdfView.currentPage { let newIndex = document.index(for: newCurrentPage) print("✅ Navigation result: Now on page \(newIndex + 1)") if newIndex == currentIndex { print("⚠️ WARNING: Page didn't change visually!") } } } } else { print("🚫 Could not get previous page object") } default: print("🤷‍♂️ Unknown swipe direction") break } } } struct PDFViewerRepresentable: UIViewControllerRepresentable { func makeUIViewController(context: Context) -> PDFViewController { return PDFViewController() } func updateUIViewController(_ uiViewController: PDFViewController, context: Context) { // No updates needed } } You can look at the code here as well: https://github.com/vallezw/swift-bug-ios26
0
1
175
Aug ’25
PDFKit findString selection extend not working
With PDFKit in SwiftUI, I'm using the findString function to search the text of a PDF. That part works correctly, but when I use the extend function to get some of the text on both sides of the found word (ie, its context in the page), it doesn't extend. Am I doing this wrong? There is very little documentation or examples about the extend function; even the Apple page doesn't specify what the units refer to in the extend call (presumably it means characters, but I suppose it could also be pixels, or some other measurement specific to PDFs). Here is the code, and pictures of the app, the output (showing that the code can read all the text on the page), and the Acrobat Reader effect I'm trying to achieve. If the extend function truly is broken, and not just a problem in how I'm going about this, a workaround would be to use the text from the entire page, and extract the surrounding words from there, but that does get complicated, especially if there are multiple instances of the word on the page, or if the result straddles 2 pages. import PDFKit import SwiftUI struct ContentView: View { @StateObject var controller = PDFViewController() @State var searchResults:[PDFSelection] = [] var body: some View { VStack { Button { searchResults = controller.pdfView!.document!.findString("is", withOptions: [.caseInsensitive]) let fullPageText = controller.pdfView!.document!.string print(fullPageText) for result in searchResults { let beforeExtending = result.string ?? "" print("Before: \(beforeExtending)") result.extend(atEnd: 3) result.extend(atStart: 3) let afterExtending = result.string ?? "" print("After: \(afterExtending)") } } label: { Text("Do search") } PDFKitView(url: generateURL(), controller: controller) } .padding() } func generateURL() -> URL { let bundlePathRootAsString = Bundle.main.resourcePath! var pdfPathInBundle = URL(fileURLWithPath: bundlePathRootAsString) pdfPathInBundle.append(path: "TestPDF.pdf") return pdfPathInBundle } } struct PDFKitView: UIViewRepresentable { func updateUIView(_ uiView: PDFView, context: Context) { } let url: URL @ObservedObject var controller: PDFViewController func makeUIView(context: Context) -> PDFView { let pdfView = PDFView() pdfView.document = PDFDocument(url: self.url) pdfView.autoScales = true controller.pdfView = pdfView return pdfView } } class PDFViewController: ObservableObject { var pdfView: PDFView? }
2
0
161
Jul ’25
Does the canvas view on top of the PDFView not re-render?
I added a canvas view using PDFPageOverlayViewProvider. When I zoom the PDFView, the drawing is scaled, but its quality becomes blurry. How can I fix this? import SwiftUI import PDFKit import PencilKit import CoreGraphics struct ContentView: View { var body: some View { if let url = Bundle.main.url(forResource: "sample", withExtension: "pdf"), let data = try? Data(contentsOf: url), let document = PDFDocument(data: data) { PDFRepresentableView(document: document) } else { Text("fail") } } } #Preview { ContentView() } struct PDFRepresentableView: UIViewRepresentable { let document: PDFDocument let pdfView = PDFView() func makeUIView(context: Context) -> PDFView { pdfView.displayMode = .singlePageContinuous pdfView.usePageViewController(false) pdfView.displayDirection = .vertical pdfView.pageOverlayViewProvider = context.coordinator pdfView.document = document pdfView.autoScales = false pdfView.minScaleFactor = 0.7 pdfView.maxScaleFactor = 4 return pdfView } func updateUIView(_ uiView: PDFView, context: Context) { // Optional: update logic if needed } func makeCoordinator() -> CustomCoordinator { return CustomCoordinator(parent: self) } } class CustomCoordinator: NSObject, PDFPageOverlayViewProvider, PKCanvasViewDelegate { let parent: PDFRepresentableView init(parent: PDFRepresentableView) { self.parent = parent } func pdfView(_ view: PDFView, overlayViewFor page: PDFPage) -> UIView? { let result = UIView() let canvasView = PKCanvasView() canvasView.drawingPolicy = .anyInput canvasView.tool = PKInkingTool(.pen, color: .blue, width: 20) canvasView.translatesAutoresizingMaskIntoConstraints = false result.addSubview(canvasView) NSLayoutConstraint.activate([ canvasView.leadingAnchor.constraint(equalTo: result.leadingAnchor), canvasView.trailingAnchor.constraint(equalTo: result.trailingAnchor), canvasView.topAnchor.constraint(equalTo: result.topAnchor), canvasView.bottomAnchor.constraint(equalTo: result.bottomAnchor) ]) for subView in view.documentView?.subviews ?? [] { subView.isUserInteractionEnabled = true } result.layoutIfNeeded() return result } }
1
0
229
Jul ’25
CanvasView overlay on PDFKit loses quality when zoomed – how to preserve drawing resolution?
Hi all, I’m currently building a SwiftUI app that overlays a PKCanvasView onto each page of a PDFView using PDFPageOverlayViewProvider. It works well at the initial scale, but once I zoom into the PDF, the drawings on the PKCanvasView appear blurry or pixelated, even though the PDF itself remains crisp. I’m trying to adjust canvasView.contentScaleFactor relative to pdfView.scaleFactor to preserve the drawing quality. Here’s a simplified version of the relevant code: import SwiftUI import PDFKit import PencilKit struct ContentView: View { var body: some View { if let url = Bundle.main.url(forResource: "sample", withExtension: "pdf"), let data = try? Data(contentsOf: url), let document = PDFDocument(data: data) { PDFRepresentableView(document: document) } else { Text("") } } } #Preview { ContentView() } struct PDFRepresentableView: UIViewRepresentable { let document: PDFDocument let pdfView = PDFView() func makeUIView(context: Context) -> PDFView { pdfView.displayMode = .singlePageContinuous pdfView.usePageViewController(false) pdfView.displayDirection = .vertical pdfView.pageOverlayViewProvider = context.coordinator pdfView.document = document pdfView.autoScales = false pdfView.minScaleFactor = 0.7 pdfView.maxScaleFactor = 4 NotificationCenter.default.addObserver( context.coordinator, selector: #selector(context.coordinator.onPageZoomAndPan), name: .PDFViewScaleChanged, object: pdfView ) return pdfView } func updateUIView(_ uiView: PDFView, context: Context) { // Optional: update logic if needed } func makeCoordinator() -> CustomCoordinator { return CustomCoordinator(parent: self) } } class CustomCoordinator: NSObject, PDFPageOverlayViewProvider, PKCanvasViewDelegate { let parent: PDFRepresentableView init(parent: PDFRepresentableView) { self.parent = parent } func pdfView(_ view: PDFView, overlayViewFor page: PDFPage) -> UIView? { let canvasView = PKCanvasView() let rect = page.bounds(for: .mediaBox) canvasView.drawingPolicy = .anyInput canvasView.tool = PKInkingTool(.pen, color: .black, width: 10) canvasView.translatesAutoresizingMaskIntoConstraints = true canvasView.backgroundColor = .red.withAlphaComponent(0.1) canvasView.frame = rect canvasView.isScrollEnabled = false for subView in view.documentView?.subviews ?? [] { subView.isUserInteractionEnabled = true } return canvasView } @objc func onPageZoomAndPan() { parent.pdfView.documentView?.subviews.forEach { subview in if subview.theClassName == "PDFPageView", let pageViewPrivate = subview.value(forKey: "_private") as? NSObject, let page = pageViewPrivate.value(forKey: "page") as? PDFPage { subview.subviews.forEach { subview in if let canvasView = subview as? PKCanvasView { let zoomScale = parent.pdfView.scaleFactor canvasView.contentScaleFactor = UIScreen.main.scale * zoomScale canvasView.drawing = canvasView.drawing canvasView.setNeedsDisplay() canvasView.layoutIfNeeded() } } } } print("Zoom changed. Current scale: \(parent.pdfView.scaleFactor)") } } extension NSObject { var theClassName: String { return NSStringFromClass(type(of: self)) } } But this doesn’t seem to improve the rendered quality. The lines still appear blurry when zoomed in. What I’ve tried: • Adjusting contentScaleFactor and forcing redraw • Reassigning canvasView.drawing • Calling setNeedsDisplay() and layoutIfNeeded() None of these approaches seem to re-render the canvas at a higher resolution or match the zoomed scale of the PDF. My questions: 1. Is there a correct way to scale PKCanvasView content to match PDF zoom levels? 2. Should I recreate the canvas or drawing when zoom changes? 3. Is PKCanvasView just not intended to handle high zoom fidelity? If anyone has successfully overlaid high-resolution canvas drawing on a zoomable PDFView, I’d love to hear how you managed it. Thanks in advance!
0
0
144
Jul ’25