Существует множество ресурсов о том, как отображать PDF-файлы в приложениях UIView
. Сейчас я работаю над созданием PDF-файла UIViews
.
Например, у меня есть UIView
, с подвидами , как TextViews, UILabels
, UIImages
, так как я могу преобразовать масштабно UIView
, как в целом , включая все его подвиды и subsubviews в формат PDF?
Я проверил ссылку на iOS от Apple . Однако здесь говорится только о записи фрагментов текста / изображения в файл PDF.
Проблема, с которой я столкнулся, заключается в том, что содержимого, которое я хочу записать в файл в формате PDF, очень много. Если я напишу их в PDF по частям, это будет огромной работой. Вот почему я ищу способ писать UIViews
в PDF-файлы или даже растровые изображения.
Я пробовал исходный код, который скопировал из других вопросов и ответов в Stack Overflow. Но он дает мне только пустой PDF-файл с UIView
ограниченным размером.
-(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);
}
Кроме того, если кому-то интересно, вот код 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) } }
источник
Если кому-то интересно, вот код 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) } }
источник
completion: (success: Bool) -> ()
для случаев возврата охранниковСупер простой способ создать PDF-файл из UIView - использовать расширение 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 "" } } }
Кредит: http://www.swiftdevcenter.com/create-pdf-from-uiview-wkwebview-and-uitableview/
источник
С Swift 5 / прошивкой 12, вы можете объединить
CALayer
«srender(in:)
метод сUIGraphicsPDFRenderer
» swritePDF(to:withActions:)
метод для того , чтобы создать PDF - файл изUIView
экземпляра.В следующем примере кода игровой площадки показано, как использовать
render(in:)
иwritePDF(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)") }
Примечание: для использования
playgroundSharedDataDirectory
на вашей игровой площадке вам сначала необходимо создать папку под названием «Общие данные игровой площадки» в папке «Документы» macOS.UIViewController
Подкласс полная реализация ниже показывает возможный способ реорганизовать предыдущий пример для приложения 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)") } } }
источник
Это сгенерирует PDF из UIView и откроет диалоговое окно печати, цель C. Прикрепите
- (IBAction)PrintPDF:(id)sender
к кнопке на экране. Добавить#import <QuartzCore/QuartzCore.h>
фреймворкH файл
@interface YourViewController : UIViewController <MFMailComposeViewControllerDelegate,UIPrintInteractionControllerDelegate> { UIPrintInteractionController *printController; } - (IBAction)PrintPDF:(id)sender;
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]; } }
источник
Я не знаю почему, но ответ casilic дает мне пустой экран на iOS6.1. Код ниже работает.
-(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; }
источник