Display and manipulate PDF documents in your applications using PDFKit.

Posts under PDFKit tag

200 Posts

Post

Replies

Boosts

Views

Activity

WKWebView doesn't show edit menu for pdf documents.
I've noticed that edit menu with Copy, Look Up, Translate options doesn't appear when I select some text in pdf file loaded in WKWebView. This issue is reproducible on the latest iOS 16 and 17 beta versions. Additionally, these two WKUIDelegate methods are called for all types of documents except PDFs. func webView(_ webView: WKWebView, willPresentEditMenuWithAnimator animator: UIEditMenuInteractionAnimating) func webView(_ webView: WKWebView, willDismissEditMenuWithAnimator animator: UIEditMenuInteractionAnimating) Is this a bug or is there a new WebKit/PDFKit API I could use to enable this menu? Feedback ID: FB12759407
0
0
796
Aug ’23
How to get this example to work?
Hello there, I am trying to follow along with the video and copy the example shown here in SwiftUI. I am given the error Cannot assign value of type 'UIView' to type 'PKCanvasView?' on this line: resultView = overlayView It is totally possible that I am botching the whole thing up but I would appreciate it if someone looked over my code. Thanks. code: // ContentView.swift import SwiftUI import PDFKit import PencilKit import Foundation import UIKit struct PDFUIView: View { let pdfDoc: PDFDocument let pdfView: PDFView init() { let url = Bundle.main.url(forResource: "example", withExtension: "pdf")! pdfDoc = PDFDocument(url: url)! pdfView = PDFView() } var body: some View { VStack { PDFKitView(showing: pdfDoc, pdfView: pdfView) } .padding() } } #Preview { PDFUIView() } struct PDFKitView: UIViewRepresentable { let pdfDocument: PDFDocument let pdfView: PDFView init(showing pdfDoc: PDFDocument, pdfView:PDFView) { self.pdfDocument = pdfDoc self.pdfView = pdfView } func makeUIView(context: Context) -> PDFView { pdfView.usePageViewController(true) pdfView.autoScales = true pdfView.pageOverlayViewProvider = context.coordinator pdfView.displayMode = .singlePageContinuous pdfView.isUserInteractionEnabled = true pdfView.document = pdfDocument pdfView.delegate = context.coordinator return pdfView } func updateUIView(_ pdfView: PDFView, context: Context) { pdfView.document = pdfDocument } func makeCoordinator() -> Coordinator { Coordinator() } } class Coordinator: NSObject, PDFPageOverlayViewProvider, PDFViewDelegate { var pageToViewMapping = [PDFPage: UIView]() func pdfView(_ view: PDFView, overlayViewFor page: PDFPage) -> UIView? { var resultView: PKCanvasView? = nil if let overlayView = pageToViewMapping[page] { resultView = overlayView } else { var canvasView = PKCanvasView(frame: .zero) canvasView.drawingPolicy = .anyInput canvasView.tool = PKInkingTool(.pen, color: .systemCyan, width: 20) canvasView.backgroundColor = UIColor.clear pageToViewMapping[page] = canvasView resultView = canvasView } let page = page as! MyPDFPage if let drawing = page.drawing { resultView?.drawing = drawing } return resultView } func pdfView(_ pdfView: PDFView, willDisplayOverlayView overlayView: UIView, for page: PDFPage) { guard let overlayView = overlayView as? PKCanvasView else { return } guard let canvasView = pageToViewMapping[page] else { return } let page = page as! MyPDFPage page.drawing = overlayView.drawing pageToViewMapping.removeValue(forKey: page) } class MyPDFAnnotation: PDFAnnotation { override func draw(with box: PDFDisplayBox, in context: CGContext) { UIGraphicsPushContext(context) context.saveGState() let page = self.page as! MyPDFPage if let drawing = page.drawing { let image = drawing.image(from: drawing.bounds, scale: 1) image.draw(in: drawing.bounds) } context.restoreGState() UIGraphicsPopContext() } } class MyPDFPage: PDFPage { var drawing: PKDrawing? } }
1
0
1.4k
Jul ’23
How to use PDFPageOverlayViewProvider?
I'm trying to use PDFPageOverlayViewProvider by copying the code provided in the "What's new in PDFKit" WWDC22 session here: https://developer.apple.com/videos/play/wwdc2022/10089/ I've copied the method implementations and set my pdfView's pageOverlayViewProvider property to the view where I implemented the protocol. However, when I try to run my app, the pdfView(_ view: PDFView, overlayViewFor page: PDFPage) method is never getting called. Has anyone been able to get this working successfully?
5
1
3.9k
Jul ’23
wwdc2022-10089 issue
Hi, I'm trying to use PencilKit over PDFKit as described in https://developer.apple.com/videos/play/wwdc2022/10089/. The thing is I open my custom UIDocument and initialize all its content to feed PDFView. Everything seems to work, I Input sketches in the canvas, PDFPageOverlayViewProvider's overlayView(for:) generates canvas correctly (it seems) but when editing finishes : willEndDisplayingOverlayView never gets called, and when I save the UIDocument (I use document.close(completionHandler:)) contents(forType:) never sees my custom PDFPages and I get no content for sketches. Does anyone of you have an idea of the lifecycle we should follow to get the methods called ? Sincerely yours
2
0
958
Jul ’23
Codes are not working at this video.
https://developer.apple.com/videos/play/wwdc2022/10089/ I am trying to run codes about PDFPageOverlayViewProvider, but the codes are not working. I cannot see what I wrote or annotate. Anyone know how can I solve and make this code working?  func pdfView(_ view: PDFView, overlayViewFor page: PDFPage) -> UIView? {         var resultView: PKCanvasView? = nil         if let overlayView = pageToViewMapping[page] {             resultView = (overlayView as! PKCanvasView)         } else {             let canvasView = PKCanvasView(frame: .zero)             canvasView.drawingPolicy = .anyInput             canvasView.tool = PKInkingTool(.pen, color: .yellow, width: 20)             canvasView.backgroundColor = .clear             pageToViewMapping[page] = canvasView             resultView = canvasView         }         let page = page as! WatermarkPage         if let drawing = page.drawing {             resultView?.drawing = drawing         }         return resultView     }          func pdfView(_ pdfView: PDFView, willEndDisplayingOverlayView overlayView: UIView, for page: PDFPage) {         let overlayView = overlayView as! PKCanvasView         let page = page as! WatermarkPage         page.drawing = overlayView.drawing         pageToViewMapping.removeValue(forKey: page)     }
2
0
1.2k
Jul ’23
QLPreviewController is not saving file for Large Size PDF
I am using QLPreviewController with SwiftUI using UIViewControllerRepresentable. If I try to delete or insert pages of large size PDF, QLPreviewController is not calling delegate methods (didUpdateContentsOf, didSaveEditedCopyOf). struct QuickLookController: UIViewControllerRepresentable { @Environment(\.dismiss) var dismiss weak var delegate: QLPreviewControllerDelegate? weak var dataSource: QLPreviewControllerDataSource? func makeUIViewController(context: Context) -> UINavigationController { let controller = context.coordinator.controller controller.delegate = delegate controller.dataSource = dataSource controller.navigationItem.rightBarButtonItem = context.coordinator.dismissButton return UINavigationController(rootViewController: controller) } func updateUIViewController(_ viewController: UINavigationController, context: UIViewControllerRepresentableContext<QuickLookController>) { } func makeCoordinator() -> Self.Coordinator { .init(parent: self) } @MainActor class Coordinator: NSObject { var parent: QuickLookController init(parent: QuickLookController) { self.parent = parent } lazy var controller: QLPreviewController = { let controller = QLPreviewController() return controller }() lazy var dismissButton: UIBarButtonItem = { let button = UIBarButtonItem( title: NSLocalizedString("Done", comment: ""), style: .plain, target: self, action: #selector(rightButtonTapped(_:)) ) button.tag = 2 return button }() @objc func rightButtonTapped(_ sender: Any) { controller.dismiss(animated: true) } } } // MARK: QuickLook extension ViewerModel: QLPreviewControllerDataSource, QLPreviewControllerDelegate { public func numberOfPreviewItems(in controller: QLPreviewController) -> Int { 1 } public func previewController( _ controller: QLPreviewController, previewItemAt index: Int ) -> QLPreviewItem { let title = self.document .documentURL? .lastPathComponent ?? "" let url = PDFManager .directory .appendingPathComponent(title) as NSURL return url as QLPreviewItem } public func previewControllerDidDismiss(_ controller: QLPreviewController) { } public func previewControllerWillDismiss(_ controller: QLPreviewController) { } ✔️ It's same even if I set it to updateContents public func previewController(_ controller: QLPreviewController, editingModeFor previewItem: QLPreviewItem) -> QLPreviewItemEditingMode { .createCopy } ✔️ Not called with Large Size PDF public func previewController(_ controller: QLPreviewController, didUpdateContentsOf previewItem: QLPreviewItem) { } ✔️ Not called with Large Size PDF public func previewController(_ controller: QLPreviewController, didSaveEditedCopyOf previewItem: QLPreviewItem, at modifiedContentsURL: URL) { } }
0
0
1k
Jul ’23
how do I print the contents of the PdfView?
XCode - Swift private var mPdfView = PDFView() private var mDocumentData: Data? mDocumentData = MakePdfDocument() mPdfView.document = PDFDocument(data: mDocumentData!) let printInfo = UIPrintInfo(dictionary: nil) printInfo.outputType = UIPrintInfo.OutputType.general printInfo.jobName = “JobName” let printController = UIPrintInteractionController.shared printController.printInfo = printInfo printController.printingItem = mPdfView printController.showsNumberOfCopies = true printController.present(animated: true, completionHandler: nil) **When print is executed, only the blank screen is output, not the generated PDF. How can I print the generated PDF content?**
2
0
1.5k
Jul ’23
PDFKit crashing randomly with error "[UIPageViewController queuingScrollView:didEndManualScroll:toRevealView:direction:animated:didFinish:didComplete:]"
We are using PDFKit to load the online PDF. It works fine for most of the cases. however sometimes app crashes with following error. "*** Assertion failure in -[UIPageViewController queuingScrollView:didEndManualScroll:toRevealView:direction:animated:didFinish:didComplete:], /SourceCache/UIKit/UIKit-3318.0.1/UIPageViewController.m:1875 2014-09-29 11:34:00.770 Wowcher[193:9460] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'No view controller managing visible view <UIView: 0x1783fa80; frame = (0 0; 320 416); autoresize = W+RM+H+BM; layer = <CALayer: 0x17898540>>'" we are not using UIPageViewController explicitly anywhere. Therefore not able to fix this issue. Any solution ?
0
1
742
Jul ’23
How to create custom edit menu and remove the default edit menu which is shown in pdfView for iOS 16
I am not getting any action callback on the default Highlight edit menu, when selecting the text and pressing the Highlight edit menu, where do we get the callback of this edit menu? Also I am trying to remove this default edit menu and trying to add a set of new edit menus but some of the default edit menu is not getting removed. So how can we achieve this Do we need to use UIEditMenuIntraction to add a new edit menu since in iOS 16 UIMenuController is deprecated, if yes then how to implement it on the text selection in pdfview. For iOS 16 I have tried to override the default edit menus using UIMenuBuilder and added a few new edit menus as a sibling, but unable to remove the default edit menu ex-(`Highlight'). - (void)buildMenuWithBuilder:(id<UIMenuBuilder>)builder{ if (@available(iOS 16.0, *)) { [builder removeMenuForIdentifier:UIMenuLookup]; [builder removeMenuForIdentifier:UIMenuReplace]; [builder removeMenuForIdentifier:UIMenuShare]; [builder removeMenuForIdentifier:UIMenuFormat]; // Add new .textStyle action UIAction *testMenuItem = [UIAction actionWithTitle:@"Test" image:nil identifier:nil handler:^(UIAction *action){ NSLog(@"action callback"); }]; [builder replaceChildrenOfMenuForIdentifier:UIMenuStandardEdit fromChildrenBlock:^NSArray<UIMenuElement *> * _Nonnull(NSArray<UIMenuElement *> * _Nonnull existingChildren) { NSMutableArray *children = [NSMutableArray arrayWithArray:existingChildren]; [children addObject:testMenuItem]; return children; }]; } [super buildMenuWithBuilder:builder]; } Also tried canPerformAction method to get the action callback of default Highlight edit menus and tried to the removed default edit menus by returning No but no luck. - (BOOL)canPerformAction:(SEL)action withSender:(id)sender { BOOL can = [super canPerformAction:action withSender:sender]; return NO; }
2
1
1.6k
Jul ’23
App crash with *** CFRelease() called with NULL *** when PDFTileSurface releaseSurface is called
We noticed a small number of crashes in iOS15/16 when user are viewing out EPaper with is a PDFView. From the stack trace, this is happening when releaseSurface is called in PDFTileSurface, and an error occurs due to CFRelease() called with NULL. Is there any way we can avoid this crash from our application? 0 CoreFoundation 0x198594 CFRelease.cold.1 + 16 1 CoreFoundation 0x7b83c CFRetain + 206 2 PDFKit 0x3051c -[PDFTileSurface releaseSurface] + 48 3 PDFKit 0x31668 -[PDFTilePool releasePDFTileSurface:] + 172 4 PDFKit 0x34638 -[PDFPageLayerTile dealloc] + 92 5 CoreFoundation 0x6ec40 -[__NSArrayI_Transfer dealloc] + 80 6 libobjc.A.dylib 0x19a4 AutoreleasePoolPage::releaseUntil(objc_object**) + 192 7 libobjc.A.dylib 0x4dac objc_autoreleasePoolPop + 252 8 UIKitCore 0x4f5ac -[UIScrollView setContentOffset:] + 1164 9 UIKitCore 0xb587c -[UIScrollView _smoothScrollSyncWithUpdateTime:] + 2156 10 UIKitCore 0xb4fd0 -[UIScrollView _smoothScrollWithUpdateTime:] + 240 11 UIKitCore 0x360fd8 -[UIScrollView _smoothScrollDisplayLink:] + 476 12 QuartzCore 0x27614 CA::Display::DisplayLink::dispatch_items(unsigned long long, unsigned long long, unsigned long long) + 832 13 QuartzCore 0x38698 display_timer_callback(__CFMachPort*, void*, long, void*) + 368 14 CoreFoundation 0x76c34 __CFMachPortPerform + 172 15 CoreFoundation 0x91f04 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 56 16 CoreFoundation 0x93a30 __CFRunLoopDoSource1 + 512 17 CoreFoundation 0x7758c __CFRunLoopRun + 2324 18 CoreFoundation 0x7bb58 CFRunLoopRunSpecific + 584 19 GraphicsServices 0x1984 GSEventRunModal + 160 20 UIKitCore 0x375628 -[UIApplication _run] + 868 21 UIKitCore 0x3752a0 UIApplicationMain + 312```
2
2
1.4k
Jun ’23
PDFKit Annotations Accessibility
I noticed that the PDFAnnotations added to a PDFPageView are not taking the accessibility properties as part of the data that later is being reported by the Accessibility Inspector. And also it seems this class: PDFNodeAccessibilityElement is not exposed from PDFKit. Anyone knows a way to override the Accessibility information for a PDF Annotation? Another issue I saw is that when you remove the PDF Annotation from the page, the Accessibility Inspector still shows it as if the annotation stayed there. Tried multiple ways to find a way to force the Accessibilty nodes to refresh, but sill haven't found a way for doing it. Would be great to hear if anyone had to deal with this kind of issues before
1
0
955
Jun ’23
How to modify default context menu of PDFKit with SwiftUI
I am creating an app for iOS and iPadOS using PDFKit based on SwiftUI and have a problem that I cannot solve. In the current app, when viewing a PDF, I select a sentence by dragging it, press and hold, and a context menu with several processing commands is displayed. This context menu is not prepared by me, but it is the default context menu that comes with PDFKit. Some of them are not suitable for my application and I want to hide them. I have searched a lot about the settings and it seems to use UIContextMenuInteraction, UIEditMenuInteraction and their delegate, canperformaction and so on. However, there is no official information on how to use them in swiftui, and when I try to implement them myself, they don't work as expected. If anyone knows how to modify the context menu provided by default when using PDFKit with SwiftUI, please let me know.
0
0
873
Jun ’23
PDFKit + SwiftUI
Hello and thanks for reading my post. I have been trying hard to generate a PDF from a SwiftUI view on a button press. Looked at the PDFKit documentation, understood that PDFView, PDFDocument and PDFPage are important classes. However, I couldn't find any examples of how to use them in SwiftUI or Swift. Basically, given a SwiftUI view (or a Swift struct), how to create a new SwiftUI view that displays the generated PDF? The pdf can contain charts, layouts, etc.
1
0
1.7k
Jun ’23
How to export a View in multiple A4 PDF pages?
I have been trying to find a way to export a View in SWIFTUI in A4 size pages PDF. The view cannot fit in one single page. So far I have managed to edit (with the help of ChatGPT) the code found in PDF Creator GitHub (See below) But although I get multiple page PDF as a result only the first page is populated, the rest are just blank. Does anyone faced something similar before, if yes how did you manage to export to PDF in A4 pages... Thanks for any tips and help! extension View{ func sharePDF<Content: View> (@ViewBuilder content: @escaping () -> Content, fileName: String) { exportPDF(content: content, completion: { status , url in if let url = url, status { ShareSheet.instance.share(items: [url]) } else { print("⚠️ Failed to make PDF") } }, fileName: fileName) } // MARK: Extracting View's Height and width with the Help of Hosting Controller and ScrollView fileprivate func convertToScrollView<Content: View>(@ViewBuilder content: @escaping ()->Content)->UIScrollView{ let scrollView = UIScrollView() // MARK: Converting SwiftUI View to UIKit View let hostingController = UIHostingController(rootView: content()).view! hostingController.translatesAutoresizingMaskIntoConstraints = false // MARK: Constraints let constraints = [ hostingController.leadingAnchor.constraint(equalTo: scrollView.leadingAnchor), hostingController.trailingAnchor.constraint(equalTo: scrollView.trailingAnchor), hostingController.topAnchor.constraint(equalTo: scrollView.topAnchor), hostingController.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor), // Width Anchor hostingController.widthAnchor.constraint(equalToConstant: screenBounds().width) ] scrollView.addSubview(hostingController) scrollView.addConstraints(constraints) scrollView.layoutIfNeeded() return scrollView } // MARK: Export to PDF // MARK: Completion Handler will Send Status and URL fileprivate func exportPDF<Content: View>(@ViewBuilder content: @escaping () -> Content, completion: @escaping (Bool, URL?) -> (), fileName: String) { // MARK: Temp URL let documentDirectory = FileManager.default.urls(for: .cachesDirectory, in: .userDomainMask).first! // MARK: To Generate New File whenever it's generated let outputFileURL = documentDirectory.appendingPathComponent("\(fileName)\(UUID().uuidString).pdf") // MARK: PDF View let scrollView = convertToScrollView { content() } scrollView.tag = 1009 scrollView.frame = CGRect(x: 0, y: 0, width: 595.2, height: 841.8) // A4 size in points (72 points per inch) let pageSize = scrollView.frame.size let contentSize = scrollView.contentSize let pageCount = Int(ceil(contentSize.height / pageSize.height)) // Create PDF Context UIGraphicsBeginPDFContextToFile(outputFileURL.path, .zero, nil) // CHATGPT: for index in 0..<pageCount { // Begin new PDF page UIGraphicsBeginPDFPageWithInfo(CGRect(origin: .zero, size: pageSize), nil) // Calculate the visible frame for each page let visibleFrame = CGRect(x: 0, y: -pageSize.height * CGFloat(index), width: pageSize.width, height: pageSize.height) // Capture the screenshot of the visible content synchronously scrollView.clipToRect(visibleFrame) { // Take a screenshot of the visible content let screenshot = scrollView.takeScreenshot() // Draw the screenshot into the PDF context screenshot.draw(at: .zero) } } completion(true, outputFileURL) // End PDF Context UIGraphicsEndPDFContext() completion(true, outputFileURL) // Removing the added View getRootController().view.subviews.forEach { view in if view.tag == 1009 { print("Removed") view.removeFromSuperview() } } } fileprivate func screenBounds()->CGRect{ return UIScreen.main.bounds } fileprivate func getRootController()->UIViewController{ guard let screen = UIApplication.shared.connectedScenes.first as? UIWindowScene else{ return .init() } guard let root = screen.windows.first?.rootViewController else{ return .init() } return root } fileprivate func getSafeArea()->UIEdgeInsets{ guard let screen = UIApplication.shared.connectedScenes.first as? UIWindowScene else{ return .zero } guard let safeArea = screen.windows.first?.safeAreaInsets else{ return .zero } return safeArea } } extension UIView { func takeScreenshot() -> UIImage { UIGraphicsBeginImageContextWithOptions(bounds.size, false, UIScreen.main.scale) drawHierarchy(in: bounds, afterScreenUpdates: true) let image = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() return image ?? UIImage() } func clipToRect(_ rect: CGRect, perform: () -> Void) { guard let context = UIGraphicsGetCurrentContext() else { return } context.saveGState() context.clip(to: rect) perform() context.restoreGState() } }
1
1
1.3k
Jun ’23
PDF Page external links ( hyperlink) are not working after rendering PDF content to UIView in Swift iOS
The pdf that has external weblink on the first page for accessing they youtube. When i open it pdf of reader or other apps it will be asked open the youtube. I want to support that functionality in UIView level. I copied PDF content to UIView successfully and but cannot see any action, once i click the external web link. Here is the my code steps: Storing pdf file in project level (Doc.pdf) Take the first page and convert that page to Data. (During the practical scenario, i need to store that value as Data first, it will be needed reuse later, So cannot use PDFPage object for processing directly.). Binding Data object with CanvasView and override the CanvasView draw method for copying pdf data to UIView. (During practical scenario, I can't use PDFView object, I have to use custom UIView and it will be needed support other customize operation (ex: erasing, cut, copy etc) Finally, even though all contents are copied successfully, i cannot see any action, once i clicked the external web link. Here is the code example: ViewController.Swift import PDFKit class ViewController: UIViewController { var pdfDocument: PDFDocument? override func loadView() { super.loadView() } func getData(pdfPage: PDFPage) -> Data { let cropBox = pdfPage.bounds(for: .cropBox) var adjustedCropBox = cropBox if ((pdfPage.rotation == 90) || (pdfPage.rotation == 270) || (pdfPage.rotation == -90)) { adjustedCropBox.size = CGSize(width: cropBox.height, height: cropBox.width) } let renderer = UIGraphicsPDFRenderer(bounds: adjustedCropBox) return renderer.pdfData { (ctx) in ctx.beginPage() ctx.cgContext.setFillColor(UIColor.white.cgColor) ctx.fill(adjustedCropBox) pdfPage.transform(ctx.cgContext, for: .cropBox) switch pdfPage.rotation { case 0: ctx.cgContext.translateBy(x: 0, y: adjustedCropBox.height) ctx.cgContext.scaleBy(x: 1, y: -1) case 90: ctx.cgContext.scaleBy(x: 1, y: -1) ctx.cgContext.rotate(by: -.pi / 2) case 180, -180: ctx.cgContext.scaleBy(x: 1, y: -1) ctx.cgContext.translateBy(x: adjustedCropBox.width, y: 0) ctx.cgContext.rotate(by: .pi) case 270, -90: ctx.cgContext.translateBy(x: adjustedCropBox.height, y: adjustedCropBox.width) ctx.cgContext.rotate(by: .pi / 2) ctx.cgContext.scaleBy(x: -1, y: 1) default: break } pdfPage.draw(with: .cropBox, to: ctx.cgContext) } } override func viewDidLoad() { super.viewDidLoad() let fileUrl = Bundle.main.url(forResource: "Doc", withExtension: "pdf") guard let fileUrl else { return } pdfDocument = PDFDocument(url: fileUrl) let firstPage: PDFPage? = pdfDocument?.page(at: 0) print("first page annotation count \(firstPage?.annotations.count)") guard let firstPage else { return } let pdfData = getData(pdfPage: firstPage) let canvasView = CanvasView(data: pdfData) self.view.addSubview(canvasView) NSLayoutConstraint.activate([ canvasView.topAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.topAnchor), canvasView.leadingAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.leadingAnchor, constant: 0), canvasView.bottomAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.bottomAnchor), canvasView.trailingAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.trailingAnchor, constant: 0) ]) } } CanvasView.Swift import PDFKit class CanvasView: UIView { var page: PDFPage? init(data: Data) { super.init(frame: .zero) translatesAutoresizingMaskIntoConstraints = false page = loadPDFPage(pdfData: data) } init(pdfPage: PDFPage){ super.init(frame: .zero) translatesAutoresizingMaskIntoConstraints = false page = pdfPage } required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } func loadPDFPage(pdfData: Data) -> PDFPage? { guard let document = PDFDocument(data: pdfData) else { return nil } return document.page(at: 0) } override func draw(_ layer: CALayer, in ctx: CGContext) { guard let page else { return } print("num of annotations - \(page.annotations.count)") if let cgPDFPage = page.pageRef { let cropBoxBounds = page.bounds(for: .cropBox) print(page.displaysAnnotations) let scaleX = layer.bounds.width / cropBoxBounds.width let scaleY = layer.bounds.height / cropBoxBounds.height ctx.saveGState() ctx.scaleBy(x: scaleX, y: scaleY) ctx.translateBy(x: -cropBoxBounds.origin.x, y: cropBoxBounds.height + cropBoxBounds.origin.y ) ctx.scaleBy(x: 1, y: -1) ctx.setFillColor(UIColor.white.cgColor) ctx.fill(cropBoxBounds) ctx.drawPDFPage(cgPDFPage) ctx.restoreGState() } } override func draw(_ rect: CGRect) {} } Here the project Special Note: Once i loaded PDFPage from url, it has two link annotations. Once i created PDFPage from Data in CavansView, i cannot see any PDF annotations and it is empty. So I assume, during data conversion process, annotations will not be considered. even though i pass original PDFPage object directly instead of Data, link click actions are not worked. So i need to someone help from how we send PDFAnnotation object data to Data object and How we can support web link behaviour as we expected. Please, help me to resolve this case and i really appreciate your feedback and help.
0
1
1k
Jun ’23
Using swift or other tool to tell if printer is connected and ready for prints
I am using SwiftUI to build a macOS app. I have to print papers and I'm trying to see if I'm actively connected to a printer. I have a default printer set as you can see in the below image but it's currently offline. My issue is the code I have returns true that I am connected to a printer because I have a saved printer device. Is there a way to check if the printer is offline even when I'm connected? In the image it says the printer is offline and I need to know how to get that. Code I'm currently using that returns true: func isConnectedToPrinter() -> Bool { let printers = NSPrinter.printerNames return !printers.isEmpty } This returns true because the printer is still remembered by my mac even though its Offline(powered down). Any idea on how mac OS can determine the printer is "Offline"? Also here is my current code to print the pdfDocument, Is there anything I can add here to help? private func printPDFDocument(forDoc document: PDFDocument) { let printInfo = NSPrintInfo.shared printInfo.horizontalPagination = .fit printInfo.verticalPagination = .fit printInfo.orientation = .portrait printInfo.topMargin = 0 printInfo.bottomMargin = 0 printInfo.leftMargin = 0 printInfo.rightMargin = 0 printInfo.isHorizontallyCentered = true printInfo.isVerticallyCentered = true let scale: PDFPrintScalingMode = .pageScaleDownToFit let printOp = document.printOperation(for: printInfo, scalingMode: scale, autoRotate: true) DispatchQueue.main.async { let result = printOp?.run() self.showLoadingText = false } }
1
1
1.2k
May ’23
iOS 16 PDF form jump to top
We build an iOS App that uses PDFView to show PDF's with annotations so the user can enter information in textfields or select checkboxes and fill out the PDF form that is than send by email. The PDF is bigger than the screen size so we need to scroll in the PDF to select the textfields. In iOS 15 and before we didn't had any problems but since we updated to iOS 16 we have the problem that the when a textfield is selected for editing or when the user stops editing by hitting the enter key the PDFViewer jumps to the top of the PDF. I also noticed that when we open the PDF everything looks fine and the PDF fits inside the PDFView. When this jumping to top has occurred we get a white section under the PDF inside the PDFView. It is as if the size from the PDF inside the PDFView is broken. Does any of you have the same Problem or is it a known problem? Is there a workaround to fix this? I couldn't find the issue tracker for PDFKit to check it myself.
0
0
770
May ’23
PDFKit - PDFPage.characterBounds(at:) returns wrong character bounds with iOS 17 beta 5
PDFKit's PDFPage.characterBounds(at: Int) is returning incorrect coordinates with iOS 17 beta 5 / Xcode 15 beta 6. Worked fine iOS 16 and earlier. It breaks critical functionality that my app relies on. I have filed feedback (FB12918701).
Replies
0
Boosts
0
Views
926
Activity
Aug ’23
WKWebView doesn't show edit menu for pdf documents.
I've noticed that edit menu with Copy, Look Up, Translate options doesn't appear when I select some text in pdf file loaded in WKWebView. This issue is reproducible on the latest iOS 16 and 17 beta versions. Additionally, these two WKUIDelegate methods are called for all types of documents except PDFs. func webView(_ webView: WKWebView, willPresentEditMenuWithAnimator animator: UIEditMenuInteractionAnimating) func webView(_ webView: WKWebView, willDismissEditMenuWithAnimator animator: UIEditMenuInteractionAnimating) Is this a bug or is there a new WebKit/PDFKit API I could use to enable this menu? Feedback ID: FB12759407
Replies
0
Boosts
0
Views
796
Activity
Aug ’23
How to get this example to work?
Hello there, I am trying to follow along with the video and copy the example shown here in SwiftUI. I am given the error Cannot assign value of type 'UIView' to type 'PKCanvasView?' on this line: resultView = overlayView It is totally possible that I am botching the whole thing up but I would appreciate it if someone looked over my code. Thanks. code: // ContentView.swift import SwiftUI import PDFKit import PencilKit import Foundation import UIKit struct PDFUIView: View { let pdfDoc: PDFDocument let pdfView: PDFView init() { let url = Bundle.main.url(forResource: "example", withExtension: "pdf")! pdfDoc = PDFDocument(url: url)! pdfView = PDFView() } var body: some View { VStack { PDFKitView(showing: pdfDoc, pdfView: pdfView) } .padding() } } #Preview { PDFUIView() } struct PDFKitView: UIViewRepresentable { let pdfDocument: PDFDocument let pdfView: PDFView init(showing pdfDoc: PDFDocument, pdfView:PDFView) { self.pdfDocument = pdfDoc self.pdfView = pdfView } func makeUIView(context: Context) -> PDFView { pdfView.usePageViewController(true) pdfView.autoScales = true pdfView.pageOverlayViewProvider = context.coordinator pdfView.displayMode = .singlePageContinuous pdfView.isUserInteractionEnabled = true pdfView.document = pdfDocument pdfView.delegate = context.coordinator return pdfView } func updateUIView(_ pdfView: PDFView, context: Context) { pdfView.document = pdfDocument } func makeCoordinator() -> Coordinator { Coordinator() } } class Coordinator: NSObject, PDFPageOverlayViewProvider, PDFViewDelegate { var pageToViewMapping = [PDFPage: UIView]() func pdfView(_ view: PDFView, overlayViewFor page: PDFPage) -> UIView? { var resultView: PKCanvasView? = nil if let overlayView = pageToViewMapping[page] { resultView = overlayView } else { var canvasView = PKCanvasView(frame: .zero) canvasView.drawingPolicy = .anyInput canvasView.tool = PKInkingTool(.pen, color: .systemCyan, width: 20) canvasView.backgroundColor = UIColor.clear pageToViewMapping[page] = canvasView resultView = canvasView } let page = page as! MyPDFPage if let drawing = page.drawing { resultView?.drawing = drawing } return resultView } func pdfView(_ pdfView: PDFView, willDisplayOverlayView overlayView: UIView, for page: PDFPage) { guard let overlayView = overlayView as? PKCanvasView else { return } guard let canvasView = pageToViewMapping[page] else { return } let page = page as! MyPDFPage page.drawing = overlayView.drawing pageToViewMapping.removeValue(forKey: page) } class MyPDFAnnotation: PDFAnnotation { override func draw(with box: PDFDisplayBox, in context: CGContext) { UIGraphicsPushContext(context) context.saveGState() let page = self.page as! MyPDFPage if let drawing = page.drawing { let image = drawing.image(from: drawing.bounds, scale: 1) image.draw(in: drawing.bounds) } context.restoreGState() UIGraphicsPopContext() } } class MyPDFPage: PDFPage { var drawing: PKDrawing? } }
Replies
1
Boosts
0
Views
1.4k
Activity
Jul ’23
How to use PDFPageOverlayViewProvider?
I'm trying to use PDFPageOverlayViewProvider by copying the code provided in the "What's new in PDFKit" WWDC22 session here: https://developer.apple.com/videos/play/wwdc2022/10089/ I've copied the method implementations and set my pdfView's pageOverlayViewProvider property to the view where I implemented the protocol. However, when I try to run my app, the pdfView(_ view: PDFView, overlayViewFor page: PDFPage) method is never getting called. Has anyone been able to get this working successfully?
Replies
5
Boosts
1
Views
3.9k
Activity
Jul ’23
wwdc2022-10089 issue
Hi, I'm trying to use PencilKit over PDFKit as described in https://developer.apple.com/videos/play/wwdc2022/10089/. The thing is I open my custom UIDocument and initialize all its content to feed PDFView. Everything seems to work, I Input sketches in the canvas, PDFPageOverlayViewProvider's overlayView(for:) generates canvas correctly (it seems) but when editing finishes : willEndDisplayingOverlayView never gets called, and when I save the UIDocument (I use document.close(completionHandler:)) contents(forType:) never sees my custom PDFPages and I get no content for sketches. Does anyone of you have an idea of the lifecycle we should follow to get the methods called ? Sincerely yours
Replies
2
Boosts
0
Views
958
Activity
Jul ’23
Codes are not working at this video.
https://developer.apple.com/videos/play/wwdc2022/10089/ I am trying to run codes about PDFPageOverlayViewProvider, but the codes are not working. I cannot see what I wrote or annotate. Anyone know how can I solve and make this code working?  func pdfView(_ view: PDFView, overlayViewFor page: PDFPage) -> UIView? {         var resultView: PKCanvasView? = nil         if let overlayView = pageToViewMapping[page] {             resultView = (overlayView as! PKCanvasView)         } else {             let canvasView = PKCanvasView(frame: .zero)             canvasView.drawingPolicy = .anyInput             canvasView.tool = PKInkingTool(.pen, color: .yellow, width: 20)             canvasView.backgroundColor = .clear             pageToViewMapping[page] = canvasView             resultView = canvasView         }         let page = page as! WatermarkPage         if let drawing = page.drawing {             resultView?.drawing = drawing         }         return resultView     }          func pdfView(_ pdfView: PDFView, willEndDisplayingOverlayView overlayView: UIView, for page: PDFPage) {         let overlayView = overlayView as! PKCanvasView         let page = page as! WatermarkPage         page.drawing = overlayView.drawing         pageToViewMapping.removeValue(forKey: page)     }
Replies
2
Boosts
0
Views
1.2k
Activity
Jul ’23
QLPreviewController is not saving file for Large Size PDF
I am using QLPreviewController with SwiftUI using UIViewControllerRepresentable. If I try to delete or insert pages of large size PDF, QLPreviewController is not calling delegate methods (didUpdateContentsOf, didSaveEditedCopyOf). struct QuickLookController: UIViewControllerRepresentable { @Environment(\.dismiss) var dismiss weak var delegate: QLPreviewControllerDelegate? weak var dataSource: QLPreviewControllerDataSource? func makeUIViewController(context: Context) -> UINavigationController { let controller = context.coordinator.controller controller.delegate = delegate controller.dataSource = dataSource controller.navigationItem.rightBarButtonItem = context.coordinator.dismissButton return UINavigationController(rootViewController: controller) } func updateUIViewController(_ viewController: UINavigationController, context: UIViewControllerRepresentableContext<QuickLookController>) { } func makeCoordinator() -> Self.Coordinator { .init(parent: self) } @MainActor class Coordinator: NSObject { var parent: QuickLookController init(parent: QuickLookController) { self.parent = parent } lazy var controller: QLPreviewController = { let controller = QLPreviewController() return controller }() lazy var dismissButton: UIBarButtonItem = { let button = UIBarButtonItem( title: NSLocalizedString("Done", comment: ""), style: .plain, target: self, action: #selector(rightButtonTapped(_:)) ) button.tag = 2 return button }() @objc func rightButtonTapped(_ sender: Any) { controller.dismiss(animated: true) } } } // MARK: QuickLook extension ViewerModel: QLPreviewControllerDataSource, QLPreviewControllerDelegate { public func numberOfPreviewItems(in controller: QLPreviewController) -> Int { 1 } public func previewController( _ controller: QLPreviewController, previewItemAt index: Int ) -> QLPreviewItem { let title = self.document .documentURL? .lastPathComponent ?? "" let url = PDFManager .directory .appendingPathComponent(title) as NSURL return url as QLPreviewItem } public func previewControllerDidDismiss(_ controller: QLPreviewController) { } public func previewControllerWillDismiss(_ controller: QLPreviewController) { } ✔️ It's same even if I set it to updateContents public func previewController(_ controller: QLPreviewController, editingModeFor previewItem: QLPreviewItem) -> QLPreviewItemEditingMode { .createCopy } ✔️ Not called with Large Size PDF public func previewController(_ controller: QLPreviewController, didUpdateContentsOf previewItem: QLPreviewItem) { } ✔️ Not called with Large Size PDF public func previewController(_ controller: QLPreviewController, didSaveEditedCopyOf previewItem: QLPreviewItem, at modifiedContentsURL: URL) { } }
Replies
0
Boosts
0
Views
1k
Activity
Jul ’23
Cannot get rid of "Highlight" context menu item in PDFView
Hello. There is a "Highlight" context menu option that shows up when a user right-clicks some selected text in a PDF. There is no way to get rid of this menu item and clicking it does nothing. How do I get rid of it? I tried overriding buildMenu(with builder: UIMenuBuilder) to remove it but that doesn't work. Help!
Replies
5
Boosts
3
Views
1.9k
Activity
Jul ’23
how do I print the contents of the PdfView?
XCode - Swift private var mPdfView = PDFView() private var mDocumentData: Data? mDocumentData = MakePdfDocument() mPdfView.document = PDFDocument(data: mDocumentData!) let printInfo = UIPrintInfo(dictionary: nil) printInfo.outputType = UIPrintInfo.OutputType.general printInfo.jobName = “JobName” let printController = UIPrintInteractionController.shared printController.printInfo = printInfo printController.printingItem = mPdfView printController.showsNumberOfCopies = true printController.present(animated: true, completionHandler: nil) **When print is executed, only the blank screen is output, not the generated PDF. How can I print the generated PDF content?**
Replies
2
Boosts
0
Views
1.5k
Activity
Jul ’23
PDFKit crashing randomly with error "[UIPageViewController queuingScrollView:didEndManualScroll:toRevealView:direction:animated:didFinish:didComplete:]"
We are using PDFKit to load the online PDF. It works fine for most of the cases. however sometimes app crashes with following error. "*** Assertion failure in -[UIPageViewController queuingScrollView:didEndManualScroll:toRevealView:direction:animated:didFinish:didComplete:], /SourceCache/UIKit/UIKit-3318.0.1/UIPageViewController.m:1875 2014-09-29 11:34:00.770 Wowcher[193:9460] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'No view controller managing visible view <UIView: 0x1783fa80; frame = (0 0; 320 416); autoresize = W+RM+H+BM; layer = <CALayer: 0x17898540>>'" we are not using UIPageViewController explicitly anywhere. Therefore not able to fix this issue. Any solution ?
Replies
0
Boosts
1
Views
742
Activity
Jul ’23
How to create custom edit menu and remove the default edit menu which is shown in pdfView for iOS 16
I am not getting any action callback on the default Highlight edit menu, when selecting the text and pressing the Highlight edit menu, where do we get the callback of this edit menu? Also I am trying to remove this default edit menu and trying to add a set of new edit menus but some of the default edit menu is not getting removed. So how can we achieve this Do we need to use UIEditMenuIntraction to add a new edit menu since in iOS 16 UIMenuController is deprecated, if yes then how to implement it on the text selection in pdfview. For iOS 16 I have tried to override the default edit menus using UIMenuBuilder and added a few new edit menus as a sibling, but unable to remove the default edit menu ex-(`Highlight'). - (void)buildMenuWithBuilder:(id<UIMenuBuilder>)builder{ if (@available(iOS 16.0, *)) { [builder removeMenuForIdentifier:UIMenuLookup]; [builder removeMenuForIdentifier:UIMenuReplace]; [builder removeMenuForIdentifier:UIMenuShare]; [builder removeMenuForIdentifier:UIMenuFormat]; // Add new .textStyle action UIAction *testMenuItem = [UIAction actionWithTitle:@"Test" image:nil identifier:nil handler:^(UIAction *action){ NSLog(@"action callback"); }]; [builder replaceChildrenOfMenuForIdentifier:UIMenuStandardEdit fromChildrenBlock:^NSArray<UIMenuElement *> * _Nonnull(NSArray<UIMenuElement *> * _Nonnull existingChildren) { NSMutableArray *children = [NSMutableArray arrayWithArray:existingChildren]; [children addObject:testMenuItem]; return children; }]; } [super buildMenuWithBuilder:builder]; } Also tried canPerformAction method to get the action callback of default Highlight edit menus and tried to the removed default edit menus by returning No but no luck. - (BOOL)canPerformAction:(SEL)action withSender:(id)sender { BOOL can = [super canPerformAction:action withSender:sender]; return NO; }
Replies
2
Boosts
1
Views
1.6k
Activity
Jul ’23
create PDF/A-3 with XML
Hi all, I create PDF from my app, but I would like to know if it's possible to create PDF/A-3 with PDFKIT and integrate XML into ?
Replies
0
Boosts
0
Views
778
Activity
Jun ’23
App crash with *** CFRelease() called with NULL *** when PDFTileSurface releaseSurface is called
We noticed a small number of crashes in iOS15/16 when user are viewing out EPaper with is a PDFView. From the stack trace, this is happening when releaseSurface is called in PDFTileSurface, and an error occurs due to CFRelease() called with NULL. Is there any way we can avoid this crash from our application? 0 CoreFoundation 0x198594 CFRelease.cold.1 + 16 1 CoreFoundation 0x7b83c CFRetain + 206 2 PDFKit 0x3051c -[PDFTileSurface releaseSurface] + 48 3 PDFKit 0x31668 -[PDFTilePool releasePDFTileSurface:] + 172 4 PDFKit 0x34638 -[PDFPageLayerTile dealloc] + 92 5 CoreFoundation 0x6ec40 -[__NSArrayI_Transfer dealloc] + 80 6 libobjc.A.dylib 0x19a4 AutoreleasePoolPage::releaseUntil(objc_object**) + 192 7 libobjc.A.dylib 0x4dac objc_autoreleasePoolPop + 252 8 UIKitCore 0x4f5ac -[UIScrollView setContentOffset:] + 1164 9 UIKitCore 0xb587c -[UIScrollView _smoothScrollSyncWithUpdateTime:] + 2156 10 UIKitCore 0xb4fd0 -[UIScrollView _smoothScrollWithUpdateTime:] + 240 11 UIKitCore 0x360fd8 -[UIScrollView _smoothScrollDisplayLink:] + 476 12 QuartzCore 0x27614 CA::Display::DisplayLink::dispatch_items(unsigned long long, unsigned long long, unsigned long long) + 832 13 QuartzCore 0x38698 display_timer_callback(__CFMachPort*, void*, long, void*) + 368 14 CoreFoundation 0x76c34 __CFMachPortPerform + 172 15 CoreFoundation 0x91f04 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 56 16 CoreFoundation 0x93a30 __CFRunLoopDoSource1 + 512 17 CoreFoundation 0x7758c __CFRunLoopRun + 2324 18 CoreFoundation 0x7bb58 CFRunLoopRunSpecific + 584 19 GraphicsServices 0x1984 GSEventRunModal + 160 20 UIKitCore 0x375628 -[UIApplication _run] + 868 21 UIKitCore 0x3752a0 UIApplicationMain + 312```
Replies
2
Boosts
2
Views
1.4k
Activity
Jun ’23
PDFKit Annotations Accessibility
I noticed that the PDFAnnotations added to a PDFPageView are not taking the accessibility properties as part of the data that later is being reported by the Accessibility Inspector. And also it seems this class: PDFNodeAccessibilityElement is not exposed from PDFKit. Anyone knows a way to override the Accessibility information for a PDF Annotation? Another issue I saw is that when you remove the PDF Annotation from the page, the Accessibility Inspector still shows it as if the annotation stayed there. Tried multiple ways to find a way to force the Accessibilty nodes to refresh, but sill haven't found a way for doing it. Would be great to hear if anyone had to deal with this kind of issues before
Replies
1
Boosts
0
Views
955
Activity
Jun ’23
How to modify default context menu of PDFKit with SwiftUI
I am creating an app for iOS and iPadOS using PDFKit based on SwiftUI and have a problem that I cannot solve. In the current app, when viewing a PDF, I select a sentence by dragging it, press and hold, and a context menu with several processing commands is displayed. This context menu is not prepared by me, but it is the default context menu that comes with PDFKit. Some of them are not suitable for my application and I want to hide them. I have searched a lot about the settings and it seems to use UIContextMenuInteraction, UIEditMenuInteraction and their delegate, canperformaction and so on. However, there is no official information on how to use them in swiftui, and when I try to implement them myself, they don't work as expected. If anyone knows how to modify the context menu provided by default when using PDFKit with SwiftUI, please let me know.
Replies
0
Boosts
0
Views
873
Activity
Jun ’23
PDFKit + SwiftUI
Hello and thanks for reading my post. I have been trying hard to generate a PDF from a SwiftUI view on a button press. Looked at the PDFKit documentation, understood that PDFView, PDFDocument and PDFPage are important classes. However, I couldn't find any examples of how to use them in SwiftUI or Swift. Basically, given a SwiftUI view (or a Swift struct), how to create a new SwiftUI view that displays the generated PDF? The pdf can contain charts, layouts, etc.
Replies
1
Boosts
0
Views
1.7k
Activity
Jun ’23
How to export a View in multiple A4 PDF pages?
I have been trying to find a way to export a View in SWIFTUI in A4 size pages PDF. The view cannot fit in one single page. So far I have managed to edit (with the help of ChatGPT) the code found in PDF Creator GitHub (See below) But although I get multiple page PDF as a result only the first page is populated, the rest are just blank. Does anyone faced something similar before, if yes how did you manage to export to PDF in A4 pages... Thanks for any tips and help! extension View{ func sharePDF<Content: View> (@ViewBuilder content: @escaping () -> Content, fileName: String) { exportPDF(content: content, completion: { status , url in if let url = url, status { ShareSheet.instance.share(items: [url]) } else { print("⚠️ Failed to make PDF") } }, fileName: fileName) } // MARK: Extracting View's Height and width with the Help of Hosting Controller and ScrollView fileprivate func convertToScrollView<Content: View>(@ViewBuilder content: @escaping ()->Content)->UIScrollView{ let scrollView = UIScrollView() // MARK: Converting SwiftUI View to UIKit View let hostingController = UIHostingController(rootView: content()).view! hostingController.translatesAutoresizingMaskIntoConstraints = false // MARK: Constraints let constraints = [ hostingController.leadingAnchor.constraint(equalTo: scrollView.leadingAnchor), hostingController.trailingAnchor.constraint(equalTo: scrollView.trailingAnchor), hostingController.topAnchor.constraint(equalTo: scrollView.topAnchor), hostingController.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor), // Width Anchor hostingController.widthAnchor.constraint(equalToConstant: screenBounds().width) ] scrollView.addSubview(hostingController) scrollView.addConstraints(constraints) scrollView.layoutIfNeeded() return scrollView } // MARK: Export to PDF // MARK: Completion Handler will Send Status and URL fileprivate func exportPDF<Content: View>(@ViewBuilder content: @escaping () -> Content, completion: @escaping (Bool, URL?) -> (), fileName: String) { // MARK: Temp URL let documentDirectory = FileManager.default.urls(for: .cachesDirectory, in: .userDomainMask).first! // MARK: To Generate New File whenever it's generated let outputFileURL = documentDirectory.appendingPathComponent("\(fileName)\(UUID().uuidString).pdf") // MARK: PDF View let scrollView = convertToScrollView { content() } scrollView.tag = 1009 scrollView.frame = CGRect(x: 0, y: 0, width: 595.2, height: 841.8) // A4 size in points (72 points per inch) let pageSize = scrollView.frame.size let contentSize = scrollView.contentSize let pageCount = Int(ceil(contentSize.height / pageSize.height)) // Create PDF Context UIGraphicsBeginPDFContextToFile(outputFileURL.path, .zero, nil) // CHATGPT: for index in 0..<pageCount { // Begin new PDF page UIGraphicsBeginPDFPageWithInfo(CGRect(origin: .zero, size: pageSize), nil) // Calculate the visible frame for each page let visibleFrame = CGRect(x: 0, y: -pageSize.height * CGFloat(index), width: pageSize.width, height: pageSize.height) // Capture the screenshot of the visible content synchronously scrollView.clipToRect(visibleFrame) { // Take a screenshot of the visible content let screenshot = scrollView.takeScreenshot() // Draw the screenshot into the PDF context screenshot.draw(at: .zero) } } completion(true, outputFileURL) // End PDF Context UIGraphicsEndPDFContext() completion(true, outputFileURL) // Removing the added View getRootController().view.subviews.forEach { view in if view.tag == 1009 { print("Removed") view.removeFromSuperview() } } } fileprivate func screenBounds()->CGRect{ return UIScreen.main.bounds } fileprivate func getRootController()->UIViewController{ guard let screen = UIApplication.shared.connectedScenes.first as? UIWindowScene else{ return .init() } guard let root = screen.windows.first?.rootViewController else{ return .init() } return root } fileprivate func getSafeArea()->UIEdgeInsets{ guard let screen = UIApplication.shared.connectedScenes.first as? UIWindowScene else{ return .zero } guard let safeArea = screen.windows.first?.safeAreaInsets else{ return .zero } return safeArea } } extension UIView { func takeScreenshot() -> UIImage { UIGraphicsBeginImageContextWithOptions(bounds.size, false, UIScreen.main.scale) drawHierarchy(in: bounds, afterScreenUpdates: true) let image = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() return image ?? UIImage() } func clipToRect(_ rect: CGRect, perform: () -> Void) { guard let context = UIGraphicsGetCurrentContext() else { return } context.saveGState() context.clip(to: rect) perform() context.restoreGState() } }
Replies
1
Boosts
1
Views
1.3k
Activity
Jun ’23
PDF Page external links ( hyperlink) are not working after rendering PDF content to UIView in Swift iOS
The pdf that has external weblink on the first page for accessing they youtube. When i open it pdf of reader or other apps it will be asked open the youtube. I want to support that functionality in UIView level. I copied PDF content to UIView successfully and but cannot see any action, once i click the external web link. Here is the my code steps: Storing pdf file in project level (Doc.pdf) Take the first page and convert that page to Data. (During the practical scenario, i need to store that value as Data first, it will be needed reuse later, So cannot use PDFPage object for processing directly.). Binding Data object with CanvasView and override the CanvasView draw method for copying pdf data to UIView. (During practical scenario, I can't use PDFView object, I have to use custom UIView and it will be needed support other customize operation (ex: erasing, cut, copy etc) Finally, even though all contents are copied successfully, i cannot see any action, once i clicked the external web link. Here is the code example: ViewController.Swift import PDFKit class ViewController: UIViewController { var pdfDocument: PDFDocument? override func loadView() { super.loadView() } func getData(pdfPage: PDFPage) -> Data { let cropBox = pdfPage.bounds(for: .cropBox) var adjustedCropBox = cropBox if ((pdfPage.rotation == 90) || (pdfPage.rotation == 270) || (pdfPage.rotation == -90)) { adjustedCropBox.size = CGSize(width: cropBox.height, height: cropBox.width) } let renderer = UIGraphicsPDFRenderer(bounds: adjustedCropBox) return renderer.pdfData { (ctx) in ctx.beginPage() ctx.cgContext.setFillColor(UIColor.white.cgColor) ctx.fill(adjustedCropBox) pdfPage.transform(ctx.cgContext, for: .cropBox) switch pdfPage.rotation { case 0: ctx.cgContext.translateBy(x: 0, y: adjustedCropBox.height) ctx.cgContext.scaleBy(x: 1, y: -1) case 90: ctx.cgContext.scaleBy(x: 1, y: -1) ctx.cgContext.rotate(by: -.pi / 2) case 180, -180: ctx.cgContext.scaleBy(x: 1, y: -1) ctx.cgContext.translateBy(x: adjustedCropBox.width, y: 0) ctx.cgContext.rotate(by: .pi) case 270, -90: ctx.cgContext.translateBy(x: adjustedCropBox.height, y: adjustedCropBox.width) ctx.cgContext.rotate(by: .pi / 2) ctx.cgContext.scaleBy(x: -1, y: 1) default: break } pdfPage.draw(with: .cropBox, to: ctx.cgContext) } } override func viewDidLoad() { super.viewDidLoad() let fileUrl = Bundle.main.url(forResource: "Doc", withExtension: "pdf") guard let fileUrl else { return } pdfDocument = PDFDocument(url: fileUrl) let firstPage: PDFPage? = pdfDocument?.page(at: 0) print("first page annotation count \(firstPage?.annotations.count)") guard let firstPage else { return } let pdfData = getData(pdfPage: firstPage) let canvasView = CanvasView(data: pdfData) self.view.addSubview(canvasView) NSLayoutConstraint.activate([ canvasView.topAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.topAnchor), canvasView.leadingAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.leadingAnchor, constant: 0), canvasView.bottomAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.bottomAnchor), canvasView.trailingAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.trailingAnchor, constant: 0) ]) } } CanvasView.Swift import PDFKit class CanvasView: UIView { var page: PDFPage? init(data: Data) { super.init(frame: .zero) translatesAutoresizingMaskIntoConstraints = false page = loadPDFPage(pdfData: data) } init(pdfPage: PDFPage){ super.init(frame: .zero) translatesAutoresizingMaskIntoConstraints = false page = pdfPage } required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } func loadPDFPage(pdfData: Data) -> PDFPage? { guard let document = PDFDocument(data: pdfData) else { return nil } return document.page(at: 0) } override func draw(_ layer: CALayer, in ctx: CGContext) { guard let page else { return } print("num of annotations - \(page.annotations.count)") if let cgPDFPage = page.pageRef { let cropBoxBounds = page.bounds(for: .cropBox) print(page.displaysAnnotations) let scaleX = layer.bounds.width / cropBoxBounds.width let scaleY = layer.bounds.height / cropBoxBounds.height ctx.saveGState() ctx.scaleBy(x: scaleX, y: scaleY) ctx.translateBy(x: -cropBoxBounds.origin.x, y: cropBoxBounds.height + cropBoxBounds.origin.y ) ctx.scaleBy(x: 1, y: -1) ctx.setFillColor(UIColor.white.cgColor) ctx.fill(cropBoxBounds) ctx.drawPDFPage(cgPDFPage) ctx.restoreGState() } } override func draw(_ rect: CGRect) {} } Here the project Special Note: Once i loaded PDFPage from url, it has two link annotations. Once i created PDFPage from Data in CavansView, i cannot see any PDF annotations and it is empty. So I assume, during data conversion process, annotations will not be considered. even though i pass original PDFPage object directly instead of Data, link click actions are not worked. So i need to someone help from how we send PDFAnnotation object data to Data object and How we can support web link behaviour as we expected. Please, help me to resolve this case and i really appreciate your feedback and help.
Replies
0
Boosts
1
Views
1k
Activity
Jun ’23
Using swift or other tool to tell if printer is connected and ready for prints
I am using SwiftUI to build a macOS app. I have to print papers and I'm trying to see if I'm actively connected to a printer. I have a default printer set as you can see in the below image but it's currently offline. My issue is the code I have returns true that I am connected to a printer because I have a saved printer device. Is there a way to check if the printer is offline even when I'm connected? In the image it says the printer is offline and I need to know how to get that. Code I'm currently using that returns true: func isConnectedToPrinter() -> Bool { let printers = NSPrinter.printerNames return !printers.isEmpty } This returns true because the printer is still remembered by my mac even though its Offline(powered down). Any idea on how mac OS can determine the printer is "Offline"? Also here is my current code to print the pdfDocument, Is there anything I can add here to help? private func printPDFDocument(forDoc document: PDFDocument) { let printInfo = NSPrintInfo.shared printInfo.horizontalPagination = .fit printInfo.verticalPagination = .fit printInfo.orientation = .portrait printInfo.topMargin = 0 printInfo.bottomMargin = 0 printInfo.leftMargin = 0 printInfo.rightMargin = 0 printInfo.isHorizontallyCentered = true printInfo.isVerticallyCentered = true let scale: PDFPrintScalingMode = .pageScaleDownToFit let printOp = document.printOperation(for: printInfo, scalingMode: scale, autoRotate: true) DispatchQueue.main.async { let result = printOp?.run() self.showLoadingText = false } }
Replies
1
Boosts
1
Views
1.2k
Activity
May ’23
iOS 16 PDF form jump to top
We build an iOS App that uses PDFView to show PDF's with annotations so the user can enter information in textfields or select checkboxes and fill out the PDF form that is than send by email. The PDF is bigger than the screen size so we need to scroll in the PDF to select the textfields. In iOS 15 and before we didn't had any problems but since we updated to iOS 16 we have the problem that the when a textfield is selected for editing or when the user stops editing by hitting the enter key the PDFViewer jumps to the top of the PDF. I also noticed that when we open the PDF everything looks fine and the PDF fits inside the PDFView. When this jumping to top has occurred we get a white section under the PDF inside the PDFView. It is as if the size from the PDF inside the PDFView is broken. Does any of you have the same Problem or is it a known problem? Is there a workaround to fix this? I couldn't find the issue tracker for PDFKit to check it myself.
Replies
0
Boosts
0
Views
770
Activity
May ’23