Istnieje wiele zasobów dotyczących sposobu wyświetlania pliku PDF w aplikacji UIView
. Teraz pracuję nad utworzeniem pliku PDF z UIViews
.
Na przykład, mam UIView
z subviews jak TextView, UILabels
, UIImages
, tak jak mogę przekonwertować Big UIView
jako całość, łącznie ze wszystkimi jego subviews i subsubviews do PDF?
Sprawdziłem referencje Apple iOS . Jednak mówi tylko o zapisywaniu fragmentów tekstu / obrazu do pliku PDF.
Problem, z którym się zmagam, polega na tym, że treści, które chcę zapisać do pliku w formacie PDF, to dużo. Jeśli napiszę je do pliku PDF kawałek po kawałku, będzie to ogromna praca. Dlatego szukam sposobu na pisanie UIViews
do plików PDF lub nawet bitmap.
Wypróbowałem kod źródłowy, który skopiowałem z innych pytań i odpowiedzi w ramach Stack Overflow. Ale daje mi tylko pusty plik PDF z UIView
rozmiarem granic.
-(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();
// draws rect to the view and thus this is captured by UIGraphicsBeginPDFContextToData
[aView drawRect:aView.bounds];
// 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);
}
Dodatkowo, jeśli ktoś jest zainteresowany, oto kod Swift 3:
func createPdfFromView(aView: UIView, saveToDocumentsWithFileName fileName: String) { let pdfData = NSMutableData() UIGraphicsBeginPDFContextToData(pdfData, aView.bounds, nil) UIGraphicsBeginPDFPage() guard let pdfContext = UIGraphicsGetCurrentContext() else { return } aView.layer.render(in: pdfContext) UIGraphicsEndPDFContext() if let documentDirectories = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first { let documentsFileName = documentDirectories + "/" + fileName debugPrint(documentsFileName) pdfData.write(toFile: documentsFileName, atomically: true) } }
źródło
Jeśli ktoś jest zainteresowany, oto kod Swift 2.1:
func createPdfFromView(aView: UIView, saveToDocumentsWithFileName fileName: String) { let pdfData = NSMutableData() UIGraphicsBeginPDFContextToData(pdfData, aView.bounds, nil) UIGraphicsBeginPDFPage() guard let pdfContext = UIGraphicsGetCurrentContext() else { return } aView.layer.renderInContext(pdfContext) UIGraphicsEndPDFContext() if let documentDirectories = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true).first { let documentsFileName = documentDirectories + "/" + fileName debugPrint(documentsFileName) pdfData.writeToFile(documentsFileName, atomically: true) } }
źródło
completion: (success: Bool) -> ()
dla przypadków powrotu strażnikówBardzo łatwym sposobem tworzenia pliku PDF z UIView jest użycie rozszerzenia UIView
Swift 4.2
extension UIView { // Export pdf from Save pdf in drectory and return pdf file path func exportAsPdfFromView() -> String { let pdfPageFrame = self.bounds let pdfData = NSMutableData() UIGraphicsBeginPDFContextToData(pdfData, pdfPageFrame, nil) UIGraphicsBeginPDFPageWithInfo(pdfPageFrame, nil) guard let pdfContext = UIGraphicsGetCurrentContext() else { return "" } self.layer.render(in: pdfContext) UIGraphicsEndPDFContext() return self.saveViewPdf(data: pdfData) } // Save pdf file in document directory func saveViewPdf(data: NSMutableData) -> String { let paths = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask) let docDirectoryPath = paths[0] let pdfPath = docDirectoryPath.appendingPathComponent("viewPdf.pdf") if data.write(to: pdfPath, atomically: true) { return pdfPath.path } else { return "" } } }
Źródło: http://www.swiftdevcenter.com/create-pdf-from-uiview-wkwebview-and-uitableview/
źródło
Swift z iOS 5/12, można połączyć
CALayer
„srender(in:)
metody zUIGraphicsPDFRenderer
” swritePDF(to:withActions:)
metody w celu utworzenia pliku PDF zeUIView
instancji.Poniższy przykładowy kod Playground pokazuje, jak używać
render(in:)
iwritePDF(to:withActions:)
:import UIKit import PlaygroundSupport let view = UIView(frame: CGRect(x: 0, y: 0, width: 100, height: 100)) view.backgroundColor = .orange let subView = UIView(frame: CGRect(x: 20, y: 20, width: 40, height: 60)) subView.backgroundColor = .magenta view.addSubview(subView) let outputFileURL = PlaygroundSupport.playgroundSharedDataDirectory.appendingPathComponent("MyPDF.pdf") let pdfRenderer = UIGraphicsPDFRenderer(bounds: view.bounds) do { try pdfRenderer.writePDF(to: outputFileURL, withActions: { context in context.beginPage() view.layer.render(in: context.cgContext) }) } catch { print("Could not create PDF file: \(error)") }
Uwaga: aby używać go
playgroundSharedDataDirectory
w Playground, musisz najpierw utworzyć folder o nazwie „Shared Playground Data” w folderze „Documents” systemu macOS.UIViewController
Podklasa pełna realizacja poniżej przedstawia możliwy sposób byłaby poprzedni przykład dla aplikacji iOS:import UIKit class ViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() let view = UIView(frame: CGRect(x: 0, y: 0, width: 100, height: 100)) view.backgroundColor = .orange let subView = UIView(frame: CGRect(x: 20, y: 20, width: 40, height: 60)) subView.backgroundColor = .magenta view.addSubview(subView) createPDF(from: view) } func createPDF(from view: UIView) { let documentDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first! let outputFileURL = documentDirectory.appendingPathComponent("MyPDF.pdf") print("URL:", outputFileURL) // When running on simulator, use the given path to retrieve the PDF file let pdfRenderer = UIGraphicsPDFRenderer(bounds: view.bounds) do { try pdfRenderer.writePDF(to: outputFileURL, withActions: { context in context.beginPage() view.layer.render(in: context.cgContext) }) } catch { print("Could not create PDF file: \(error)") } } }
źródło
Spowoduje to wygenerowanie pliku PDF z UIView i otwarcie okna dialogowego drukowania, cel C. Dołącz
- (IBAction)PrintPDF:(id)sender
do przycisku na ekranie. Dodaj#import <QuartzCore/QuartzCore.h>
strukturęPlik H.
@interface YourViewController : UIViewController <MFMailComposeViewControllerDelegate,UIPrintInteractionControllerDelegate> { UIPrintInteractionController *printController; } - (IBAction)PrintPDF:(id)sender;
Plik M.
-(void)createPDFfromUIView:(UIView*)aView saveToDocumentsWithFileName:(NSString*)aFilename { NSMutableData *pdfData = [NSMutableData data]; UIGraphicsBeginPDFContextToData(pdfData, aView.bounds, nil); UIGraphicsBeginPDFPage(); CGContextRef pdfContext = UIGraphicsGetCurrentContext(); [aView.layer renderInContext:pdfContext]; UIGraphicsEndPDFContext(); NSArray* documentDirectories = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask,YES); NSString* documentDirectory = [documentDirectories objectAtIndex:0]; NSString* documentDirectoryFilename = [documentDirectory stringByAppendingPathComponent:aFilename]; NSString *file = [documentDirectory stringByAppendingPathComponent:@"yourPDF.pdf"]; NSURL *urlPdf = [NSURL fileURLWithPath: file]; [pdfData writeToFile:documentDirectoryFilename atomically:YES]; NSLog(@"documentDirectoryFileName: %@",documentDirectoryFilename); } - (IBAction)PrintPDF:(id)sender { [self createPDFfromUIView:self.view saveToDocumentsWithFileName:@"yourPDF.pdf"]; NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); NSString *documentsDirectory = [paths objectAtIndex:0]; NSString *path = [documentsDirectory stringByAppendingPathComponent:@"yourPDF.pdf"]; NSData *myData = [NSData dataWithContentsOfFile: path]; UIPrintInteractionController *pic = [UIPrintInteractionController sharedPrintController]; if(pic && [UIPrintInteractionController canPrintData: myData] ) { pic.delegate = self; UIPrintInfo *printInfo = [UIPrintInfo printInfo]; printInfo.outputType = UIPrintInfoOutputGeneral; printInfo.jobName = [path lastPathComponent]; printInfo.duplex = UIPrintInfoDuplexLongEdge; pic.printInfo = printInfo; pic.showsPageRange = YES; pic.printingItem = myData; void (^completionHandler)(UIPrintInteractionController *, BOOL, NSError *) = ^(UIPrintInteractionController *pic, BOOL completed, NSError *error) { //self.content = nil; if(!completed && error){ NSLog(@"Print Error: %@", error); } }; [pic presentAnimated:YES completionHandler:completionHandler]; } }
źródło
Nie wiem dlaczego, ale odpowiedź Casilica daje mi pusty ekran na iOS6.1. Poniższy kod działa.
-(NSMutableData *)createPDFDatafromUIView:(UIView*)aView { // 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(); return pdfData; } -(NSString*)createPDFfromUIView:(UIView*)aView saveToDocumentsWithFileName:(NSString*)aFilename { // Creates a mutable data object for updating with binary data, like a byte array NSMutableData *pdfData = [self createPDFDatafromUIView:aView]; // 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); return documentDirectoryFilename; }
źródło