Posts

Post not yet marked as solved
0 Replies
298 Views
I’m showing a PDF page in UIView’s subview using PDFKit along with some UILabel and UIImageView. At a time I’m only showing one page in PDFView. Users can change the size and position of this PDFView. class ResizablePDFView: PDFView { override func draw(_ rect: CGRect) { super.draw(rect) } override func draw(_ layer: CALayer, in ctx: CGContext) { let isPDF = !UIGraphicsGetPDFContextBounds().isEmpty if isPDF { if let document = self.document, document.pageCount > 0, let page = document.page(at: 0) { ctx.saveGState() ctx.scaleBy(x: 1, y: -1) ctx.translateBy(x: 0, y: -bounds.size.height) let pageBounds = page.bounds(for: .mediaBox) ctx.scaleBy( x: bounds.size.width / pageBounds.size.width, y: bounds.size.height / pageBounds.size.height) ctx.translateBy(x: -pageBounds.origin.x, y: -pageBounds.origin.y) page.draw(with: .mediaBox, to: ctx) ctx.restoreGState() } }else { super.draw(layer, in: ctx) } } } class ResizableLabelView: UILabel { func setup() { self.font = UIFont.systemFont(ofSize: 20) self.textColor = UIColor.systemBlue } override func draw(_ rect: CGRect) { super.draw(rect) } override func draw(_ layer: CALayer, in ctx: CGContext) { let isPDF = !UIGraphicsGetPDFContextBounds().isEmpty if isPDF { draw(bounds) }else { super.draw(layer, in: ctx) } } } CanvasView setup, class ViewController: UIViewController { var canvasView: UIView! var pdfView: ResizablePDFView! var label: ResizableLabelView! override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view. self.view.backgroundColor = UIColor.gray self.canvasView = UIView(frame: CGRect(origin: CGPoint.zero, size: CGSize(width: 400, height: 573))) self.canvasView.center = self.view.center self.canvasView.backgroundColor = UIColor.white self.view.addSubview(self.canvasView) self.setupPDF() self.setupLabel() } func setupPDF() { self.pdfView = ResizablePDFView(frame: CGRect(origin: .zero, size: self.canvasView.frame.size)) self.pdfView.backgroundColor = UIColor.clear self.canvasView.addSubview(self.pdfView) self.pdfView.autoScales = false self.pdfView.displayMode = .singlePage self.pdfView.displaysPageBreaks = false self.pdfView.pageBreakMargins = UIEdgeInsets.zero self.pdfView.pageShadowsEnabled = false if let file = Bundle.main.url(forResource: "sample_pdf", withExtension: "pdf") { if let pdfDocument = PDFDocument(url: file) { let pageNumber: Int = 0 if let page = pdfDocument.page(at: pageNumber) { let pageDocument = PDFDocument() pageDocument.insert(page, at: 0) self.pdfView.document = pageDocument self.pdfView.minScaleFactor = self.pdfView.scaleFactorForSizeToFit self.pdfView.maxScaleFactor = self.pdfView.scaleFactorForSizeToFit self.pdfView.scaleFactor = self.pdfView.scaleFactorForSizeToFit } } } } func setupLabel() { self.label = ResizableLabelView(frame: CGRect(x: 10, y: 10, width: 200, height: 50)) self.label.setup() self.label.text = "Sample Text" self.label.sizeToFit() self.canvasView.addSubview(self.label) } } now, I'm creating the PDF from canvasView @IBAction func exportButtonAction(_ sender: UIButton) { let filePath = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!.appendingPathComponent("Exported_PDF.pdf") UIGraphicsBeginPDFContextToFile(filePath.path, .zero, [kCGPDFContextCreator as String: "PDF Export Demo App"]) guard let canvas = self.canvasView else { return } UIGraphicsBeginPDFPageWithInfo(canvas.bounds, nil) guard let context = UIGraphicsGetCurrentContext() else { return } canvas.setNeedsDisplay() canvas.layer.render(in: context) UIGraphicsEndPDFContext() print(filePath) } Now, This will render UILabel and UIImageView in PDF properly without rasterization and selectable text, but It does not draw PDFView like original pdf with links.
What am I doing wrong here? how can I debug this issue? https://drive.google.com/drive/folders/1qLcGNGWxoXbWJnr6xBxueKjPHnfxYS6D?usp=drive_link
Posted
by BV-OB.
Last updated
.