要创建此PDF,我使用Cocoa的dataWithPDF:方法,其代码如下:
do { // define bounds of PDF as the note text view let rect: NSRect = self.noteTextView.bounds // create the file path for the PDF if let dir = NSSearchPathForDirectoriesInDomains(FileManager.SearchPathDirectory.documentDirectory,FileManager.SearchPathDomainMask.allDomainsMask,true).first { // add the note title to path let path = NSURL(fileURLWithPath: dir).appendingPathComponent("Exportednote.pdf") // Create a PDF of the noteTextView and write it to the created filepath try self.noteTextView.dataWithPDF(inside: rect).write(to: path!) } else { print("Path format incorrect.") // never happens to me } } catch _ { print("something went wrong.") // never happens to me }
这完全有效,但有一个问题:PDF仅在一个页面上进行,这意味着当注释中有大量文本时页面会变得非常长.如何在我的应用程序导出PDF或之后立即强制PDF进入所需数量的信纸大小的页面?
注意:在您阅读更多内容之前,您应该知道我在Github上创建了一个简单的工具,因此您可以在更少的步骤中执行此操作(在Swift 3中,不再需要任何Objective-C). Check that out here.
第1步:正确设置应用程序沙盒.每个提交的Mac应用程序都需要正确使用App SandBoxing,因此最好只需30秒即可立即设置它.如果它尚未打开,请转到Target的设置,然后转到Capabilities标题.打开App SandBoxing,在顶部.您应该看到许多子功能,启用您的应用程序所需的任何一个,并确保将用户选定文件设置为读/写.
第2步:将此功能添加到您的代码中,这将创建一个不可见的webview并将您的文本添加到其中.
func createPDF(fromHTMLString: String) { self.webView.mainFrame.loadHTMLString(htmlString,baseURL: nil) self.delay(1) { MyCreatePDFFile(self.webView) } }
步骤3:创建delay()函数以允许Xcode等待一秒钟以将HTML加载到Web视图中.
func delay(delay:Double,closure:()->()) { dispatch_after( dispatch_time( disPATCH_TIME_Now,Int64(delay * Double(NSEC_PER_SEC)) ),dispatch_get_main_queue(),closure) }
var webView = WebView()
第5步:您可能会注意到我们尚未创建MyCreatePDFFile()函数.事实证明,没有办法将此WebView转换为带有Swift的PDF,因此我们将不得不求助于Objective-C(呻吟).是的,你将不得不在你的Swift应用程序中运行一些Objective-C.
第6步:转到文件 – >创建.m文件新 – >文件(或通过点击CMD N)然后双击Objective-C文件.将其命名为CreatePDF.m并将其保留为空文件.
单击是.
如果您没有看到提示或意外删除了桥接标题,请将新的.h文件添加到项目中并将其命名为<#YourProjectName#> -Bridging-Header.h
在某些情况下,特别是在使用ObjC框架时,您不会显式添加Objective-C类,Xcode也无法找到链接器.在这种情况下,创建如上所述命名的Bridging Header .h文件,然后确保在目标的项目设置中链接其路径,如下所示:
步骤8:转到文件 – >创建.h文件新 – >文件(或通过点击CMD N)然后双击标题文件.将其命名为CreatePDF.h.
步骤9:在CreatePDF.h文件中,添加以下代码,导入Cocoa和WebKit并设置PDF创建功能:
#ifndef CreatePDF_h #define CreatePDF_h #import <Cocoa/Cocoa.h> #import <WebKit/WebKit.h> @interface Thing : NSObject void MyCreatePDFFile(WebView *thewebview); @end #endif /* CreatePDF_h */
步骤10:设置PDF创建功能的.m文件的时间.首先将其添加到空的.m文件中:
#import "CreatePDF.h" #import <Cocoa/Cocoa.h> #import <WebKit/WebKit.h> @implementation Thing void MyCreatePDFFile(WebView *thewebview) { } @end
步骤11:现在您可以将代码添加到MyCreatePDFFile(..)函数中.这是函数本身(这是在当前空的void函数内部):
NSDictionary *printOpts = @{ nsprintJobdisposition: nsprintSaveJob // sets the print job to save the PDF instead of print it. }; nsprintInfo *printInfo = [[nsprintInfo alloc] initWithDictionary:printOpts]; [printInfo setPaperSize:NSMakeSize(595.22,841.85)]; // sets the paper size to a nice size that works,you can mess around with it [printInfo setTopMargin:10.0]; [printInfo setLeftMargin:10.0]; [printInfo setRightMargin:10.0]; [printInfo setBottomMargin:10.0]; nsprintOperation *printOp = [nsprintOperation printOperationWithView:[[[thewebview mainFrame] frameView] documentView] printInfo:printInfo]; // sets the print operation to printing the WebView as a document with the print info set above printOp.showsPrintPanel = NO; // skip the print question and go straight to saving pdf printOp.showsProgresspanel = NO; [printOp runoperation];
第12步:现在将其添加到您的桥接头,以允许您的Swift文件看到您刚刚创建的Objective-C函数.
#import "CreatePDF.h"
第13步:此代码不应该有任何错误,但如果有,请在下面评论他们.
步骤14:要从Swift文件的任何位置调用createPDF函数,请执行以下操作:
createPDF("<h1>Title!</h1><p>\(textview.text!)</p>")
您在createPDF中看到的字符串是HTML,可以编辑为任何HTML.如果你不了解HTML,你可以看到一些非常基础的东西right here.
那应该是它!您现在应该能够在Cocoa / Mac应用程序上直接从Swift创建分页PDF.
积分
> How to run Objective-C code in a Swift project,谢谢马特.
> How to write a PDF from a WebView in Obj-C,感谢一些随机的网络论坛.
> How to create a bridging header manually,感谢洛根.
> Delay function in Swift,感谢Matt.
> Images,感谢洛根.
注意:此答案经过测试,可与Xcode 7,Swift 2和OS X El Captian配合使用.如果您在使用Xcode 8 / Swift 3 / macOS Sierra时遇到任何问题,请告诉我.