Convert Swiftui View to PDF on iOS

Convert SwiftUI View to PDF on iOS

After some thinking I came up with the idea of combining the UIKit to PDF method and SwiftUI.

At first you create your SwiftUI view, then you put into an UIHostingController. You render the HostingController on a window behind all other views and and draw its layer on a PDF.
Sample code is listed below.

func exportToPDF() {

let documentDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
let outputFileURL = documentDirectory.appendingPathComponent("SwiftUI.pdf")

//Normal with
let width: CGFloat = 8.5 * 72.0
//Estimate the height of your view
let height: CGFloat = 1000
let charts = ChartsView()

let pdfVC = UIHostingController(rootView: charts)
pdfVC.view.frame = CGRect(x: 0, y: 0, width: width, height: height)

//Render the view behind all other views
let rootVC = UIApplication.shared.windows.first?.rootViewController
rootVC?.addChild(pdfVC)
rootVC?.view.insertSubview(pdfVC.view, at: 0)

//Render the PDF
let pdfRenderer = UIGraphicsPDFRenderer(bounds: CGRect(x: 0, y: 0, width: 8.5 * 72.0, height: height))

do {
try pdfRenderer.writePDF(to: outputFileURL, withActions: { (context) in
context.beginPage()
pdfVC.view.layer.render(in: context.cgContext)
})

self.exportURL = outputFileURL
self.showExportSheet = true

}catch {
self.showError = true
print("Could not create PDF file: \(error)")
}

pdfVC.removeFromParent()
pdfVC.view.removeFromSuperview()
}

Create a PDF file from a specific View

From the answer of the linked question:

You render the HostingController on a window behind all other views and and draw its layer on a PDF.

That would be the first view, index 0 I presume. From the function you gave, this line looks relevant:

rootVC?.view.insertSubview(pdfVC.view, at: 0)

Replace 0 with your desired view.

How to Convert UIView to PDF within iOS?

Note that the following method creates just a bitmap of the view; it does not create actual typography.

(void)createPDFfromUIView:(UIView*)aView saveToDocumentsWithFileName:(NSString*)aFilename
{
// Creates a mutable data object for updating with binary data, like a byte array
NSMutableData *pdfData = [NSMutableData data];

// Points the pdf converter to the mutable data object and to the UIView to be converted
UIGraphicsBeginPDFContextToData(pdfData, aView.bounds, nil);
UIGraphicsBeginPDFPage();
CGContextRef pdfContext = UIGraphicsGetCurrentContext();

// draws rect to the view and thus this is captured by UIGraphicsBeginPDFContextToData

[aView.layer renderInContext:pdfContext];

// remove PDF rendering context
UIGraphicsEndPDFContext();

// Retrieves the document directories from the iOS device
NSArray* documentDirectories = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask,YES);

NSString* documentDirectory = [documentDirectories objectAtIndex:0];
NSString* documentDirectoryFilename = [documentDirectory stringByAppendingPathComponent:aFilename];

// instructs the mutable data object to write its context to a file on disk
[pdfData writeToFile:documentDirectoryFilename atomically:YES];
NSLog(@"documentDirectoryFileName: %@",documentDirectoryFilename);
}

Also make sure you import:
QuartzCore/QuartzCore.h



Related Topics



Leave a reply



Submit