版本记录
| 版本号 | 时间 |
|---|---|
| V1.0 | 2019.09.16 星期一 |
前言
今天翻阅苹果的API文档,发现多了一个框架就PDFKit,看了下才看见是iOS11.0新添加的框架,这里我们就一起来看一下框架PDFKit。感兴趣的可以看下面几篇文章。
1. PDFKit框架详细解析 (一) —— 基本概览(一)
开始
今天过生日,祝自己生日快乐吧!
首先看下主要内容
主要内容:了解如何创建PDF,使用
Core Text和Core Graphics并通过构建应用程序来共享创建的文档。
接着看一下写作环境
Swift 5, iOS 13, Xcode 11
PDF文档充当在线和打印文档之间的桥梁。 Adobe发明了PDF格式,但它现在是一个开放标准,它定义了包含文本,图像和交互元素的文档。
此标准允许您创建看起来像打印文档的电子文档。 对于许多应用程序,创建PDF可为用户增加价值。
PDFKit在版本11.0中来到iOS。 它提供了用于显示,创建和操作PDF文档的库。
虽然PDFKit最常见的用途是添加查看PDF文档到应用程序的功能,但您也可以使用它来创建和更改PDF文件。
在本教程中,您将构建一个应用程序,根据用户输入的信息创建一个简单的flyer作为PDF。
在继续之前,您应该对iOS应用程序开发有基本的了解。 熟悉Core Text and Core Graphics将很有用,但不是必需的。
PDF文档由以.pdf扩展名结尾的单个文件组成。 该文件可以包括提供关于文档的信息的元数据。 该规范还允许简单的密码保护来限制访问和打印。
PDF文档包含与打印文档页面对应的页面。 每个页面包含文本,图像,超链接和/或注释。
该页面使用一个坐标系统,每个打印英寸有72个点。 坐标起源于页面的左下角,并向上和向右增加。
在本教程中,您将构建一个应用程序来创建简单的传单flyer。 传单将包含标题,图像,正文和底部的几个撕下标签。 该应用程序允许用户输入传单的信息,并从照片库或相机中选择照片。 用户选择图像后,将显示该图像的预览。 这是传单的外观:

打开入门项目,然后构建并运行应用程序。

您将看到一个表单,用于输入创建传单的信息。 工具栏包含一个预览Preview按钮,该按钮将创建PDF并打开带有PDFView的视图控制器以显示传单。 还有一个Share按钮,您将更新,以便您可以与其他iOS应用程序共享PDF。
Creating a PDF With PDFKit
创建PDF的关键类是UIGraphicsPDFRenderer。 过程是:
- 1) 实例化
UIGraphicsPDFRenderer对象,可选择提供描述文档的参数。 您通常希望这样做,因为如果不这样做,iOS将使用基于用户设备的默认值。 - 2) 调用
pdfData(actions :)渲染器生成Data对象,或调用writePDF(to:withActions :)渲染器将文档直接写入磁盘。 - 3) 在渲染器方法的闭包中使用
Core Graphics指令来创建文档。
接下来,您将创建一个新类来封装构建PDF的过程。 在项目中选择File ▸ New ▸ File…,然后选择iOS▸CocoaTouch Class模板。 然后单击Next。
完成后,将类命名为PDFCreator并使其成为NSObject的子类。 确保将语言设置为Swift。
最后,单击Next,然后单击Create。
1. Importing PDFKit
要使用PDFKit,您需要将其导入到类中。 在文件顶部的import UIKit下添加以下内容:
import PDFKit
现在,添加这个新方法来创建PDF到PDFCreator:
func createFlyer() -> Data {
// 1
let pdfMetaData = [
kCGPDFContextCreator: "Flyer Builder",
kCGPDFContextAuthor: "raywenderlich.com"
]
let format = UIGraphicsPDFRendererFormat()
format.documentInfo = pdfMetaData as [String: Any]
// 2
let pageWidth = 8.5 * 72.0
let pageHeight = 11 * 72.0
let pageRect = CGRect(x: 0, y: 0, width: pageWidth, height: pageHeight)
// 3
let renderer = UIGraphicsPDFRenderer(bounds: pageRect, format: format)
// 4
let data = renderer.pdfData { (context) in
// 5
context.beginPage()
// 6
let attributes = [
NSAttributedString.Key.font: UIFont.boldSystemFont(ofSize: 72)
]
let text = "I'm a PDF!"
text.draw(at: CGPoint(x: 0, y: 0), withAttributes: attributes)
}
return data
}
这是代码的作用:
- 1) 使用预定义键创建包含PDF元数据的字典。您可以在Apple的辅助字典键文档Auxiliary Dictionary Keys中找到完整的键列表。要设置元数据,请创建
UIGraphicsPDFRendererFormat对象并将字典分配给documentInfo。 - 2) 回想一下,PDF文件使用每英寸72点的坐标系。要创建具有特定大小的PDF文档,请将大小(以英寸为单位)乘以72以获得点数。在这里,您将使用
8.5 x 11英寸,因为这是标准的美国信件大小。然后创建一个刚刚计算出的大小的矩形。 - 3)
UIGraphicsPDFRenderer(bounds:format :)创建一个PDFRenderer对象,其中包含矩形的尺寸和包含元数据的格式。 - 4)
pdfData(actions :)包含一个用于创建PDF的block块。渲染器创建Core Graphics上下文,该上下文成为块中的当前上下文。在此上下文中完成的绘图将显示在PDF上。 - 5)
context.beginPage()启动一个新的PDF页面。在给出任何其他绘制命令之前,您必须先调用beginPage()一次。您可以再次调用它来创建多页PDF文档。 - 6) 在
String上使用draw(at:withAttributes :)将字符串绘制到当前上下文。您将字符串的大小设置为72磅。
现在您有一个简单的PDF,您将在应用程序中设置PDF的预览,以便您可以查看它。
Adding a PDF Preview
入门应用程序已包含PDFView以供预览,但尚未准备好使用。 要开始设置预览,请打开PDFPreviewViewController.swift。 您将把PDF作为Data对象传递给类。 在PDFPreviewViewController的顶部,添加一个变量:
public var documentData: Data?
现在在viewDidLoad()的末尾添加以下代码:
if let data = documentData {
pdfView.document = PDFDocument(data: data)
pdfView.autoScales = true
}
加载预览时,如果设置了documentData,则PDFDocument(data :)会根据传递的数据创建PDFDocument。
PDFDocument是表示PDF数据的PDFKit对象。 将document分配到PDFView视图,并将document设置为缩放以适合视图。
返回到FlyerBuilderViewController.swift并将以下方法添加到FlyerBuilderViewController的末尾。 确保将其添加到类而不是扩展名。
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "previewSegue" {
guard let vc = segue.destination as? PDFPreviewViewController else { return }
let pdfCreator = PDFCreator()
vc.documentData = pdfCreator.createFlyer()
}
}
当用户在Preview按钮上调用segue时,此方法将创建PDF。 它将PDF数据传递到目标PDFPreviewViewController。
现在,构建并运行应用程序。 单击工具栏中的Preview,您将看到在应用程序中创建的PDF文件的预览。

如前所述,PDF的坐标来自左下角。 您可能会惊讶地看到PDF文件顶部的文本,因为它是在坐标(x:0,y:0)处绘制的。 为什么会这样?
pdfData(actions :)创建一个Core Graphics上下文。Core Graphics共享相同的点大小,但Core Graphics上下文的坐标从左上角开始,向下和向右增加。如果需要在坐标空间之间进行转换,
PDFKit中的方法会执行此操作。
Adding User Text to the PDF
现在是时候开始实现传单了。 打开PDFCreator.swift并在PDFCreator的顶部添加以下行。
let title: String
let body: String
let image: UIImage
let contactInfo: String
init(title: String, body: String, image: UIImage, contact: String) {
self.title = title
self.body = body
self.image = image
self.contactInfo = contact
}
这会添加属性以存储传单的标题,正文,图像和联系信息。 您还可以定义自定义初始化方法来设置变量。
由于您拥有PDF的标题,因此现在可以通过打开PDFCreator.swift并将pdfMetaData更新为以下内容将其添加到元数据中:
let pdfMetaData = [
kCGPDFContextCreator: "Flyer Builder",
kCGPDFContextAuthor: "raywenderlich.com",
kCGPDFContextTitle: title
]
Adding the Title With Core Text
您希望传单的标题显示在PDF页面的中心和顶部附近。 为了使创建代码更易于遵循和维护,您将为传单的每个部分创建单独的方法。
添加文本时,您将希望利用Core Text提供的其他布局功能。 因此,在PDFCreator的底部添加以下新方法:
func addTitle(pageRect: CGRect) -> CGFloat {
// 1
let titleFont = UIFont.systemFont(ofSize: 18.0, weight: .bold)
// 2
let titleAttributes: [NSAttributedString.Key: Any] =
[NSAttributedString.Key.font: titleFont]
// 3
let attributedTitle = NSAttributedString(
string: title,
attributes: titleAttributes
)
// 4
let titleStringSize = attributedTitle.size()
// 5
let titleStringRect = CGRect(
x: (pageRect.width - titleStringSize.width) / 2.0,
y: 36,
width: titleStringSize.width,
height: titleStringSize.height
)
// 6
attributedTitle.draw(in: titleStringRect)
// 7
return titleStringRect.origin.y + titleStringRect.size.height
}
这是这个方法的作用:
- 1) 您创建一个大小为
18磅的系统字体实例,并以粗体显示。 - 2) 您创建属性字典并将
NSAttributedString.Key.font键设置为此字体。 - 3) 然后,创建
NSAttributedString,其中包含所选字体中标题的文本。 - 4) 在属性字符串上使用
size()会返回一个矩形,该矩形的大小为文本在当前上下文中占据的尺寸。 - 5) 现在,您可以从页面顶部创建一个36个点,该页面在页面上水平居中。下图显示了如何计算文本居中所需的
x坐标。从页面宽度中减去字符串的宽度以计算剩余空间。将此数量除以2会均匀地分割文本每一侧的空间。 - 6) 在
NSAttributedString上使用draw(in :)将其绘制在矩形内。 - 7) 此代码将矩形的
y坐标添加到矩形的高度,以查找矩形底部的坐标,如下图所示。然后代码将此坐标返回给调用者。

您将在本教程后面使用此技术更多地放置文本,因此请确保在继续之前了解它。
您现在需要在创建PDF时调用新方法。 在createFlyer()中,替换此代码:
let attributes = [
NSAttributedString.Key.font: UIFont.boldSystemFont(ofSize: 72)
]
let text = "I'm a PDF!"
text.draw(at: CGPoint(x: 0, y: 0), withAttributes: attributes)
调用新方法:
let titleBottom = addTitle(pageRect: pageRect)
接下来,您需要将标题传递给PDFCreator。 因此,打开FlyerBuilderViewController.swift并将prepare(for:sender :)的实现替换为:
guard
segue.identifier == "previewSegue",
let vc = segue.destination as? PDFPreviewViewController,
let title = flyerTextEntry.text
else {
return
}
let pdfCreator = PDFCreator(
title: title,
body: "",
image: UIImage(),
contact: ""
)
vc.documentData = pdfCreator.createFlyer()
PDFCreator初始化程序设置标题并为其余元素提供占位符值。 当您实施传单的每个部分时,您将替换这些。
现在,构建并运行应用程序。 输入标题,然后点按Preview。 您应该看到标题文本位于页面顶部的中心位置。

Adding Paragraph Text
如果您使用该应用程序尝试不同的标题,您可能会注意到一个问题:这种定位文本的方法仅在文本适合单行时才有效。 一个很长的标题将冲出PDF的两侧。

虽然标题通常是一行,但大多数文本将覆盖页面上的几行。 幸运的是,Core Text提供了NSParagraphStyle类来解决这个问题。 现在,您将了解如何将包装文本添加到应用程序。
1. Using NSParagraphStyle
要将包装文本引入您的应用,请将此新方法添加到PDFCreator.swift中PDFCreator的底部:
func addBodyText(pageRect: CGRect, textTop: CGFloat) {
let textFont = UIFont.systemFont(ofSize: 12.0, weight: .regular)
// 1
let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.alignment = .natural
paragraphStyle.lineBreakMode = .byWordWrapping
// 2
let textAttributes = [
NSAttributedString.Key.paragraphStyle: paragraphStyle,
NSAttributedString.Key.font: textFont
]
let attributedText = NSAttributedString(
string: body,
attributes: textAttributes
)
// 3
let textRect = CGRect(
x: 10,
y: textTop,
width: pageRect.width - 20,
height: pageRect.height - textTop - pageRect.height / 5.0
)
attributedText.draw(in: textRect)
}
这与您用于绘制标题的方法的不同:
- 1) 您创建一个
NSMutableParagraphStyle对象来定义文本应如何布局和换行。 自然对齐根据应用程序的本地化设置对齐。 行被设置为在分词(word breaks)时换行。 - 2) 字典包含除了字体之外还设置段落样式的文本属性。 您可以创建一个
NSAttributedString,它结合了文本和格式,就像您对标题所做的那样。 - 3) 文本的矩形有点不同。 它从左侧偏移10个点并将顶部设置为传递的值。 宽度设置为页面宽度减去每边10个边距。 高度是从顶部到页面高度的1/5到底部的距离。
下一步是更新createFlyer()以添加正文文本。 您还将在标题和正文之间添加半英寸的空格。 在调用addTitle()的下方,添加以下内容:
addBodyText(pageRect: pageRect, textTop: titleBottom + 36.0)
接下来,您需要将传单的文本传递给预览控制器。 为此,打开Flyer Builder ViewController.swift并将prepare(for:sender :)的实现替换为:
guard
segue.identifier == "previewSegue",
let vc = segue.destination as? PDFPreviewViewController,
let title = flyerTextEntry.text,
let body = bodyTextView.text
else {
return
}
let pdfCreator = PDFCreator(
title: title,
body: body,
image: UIImage(),
contact: ""
)
vc.documentData = pdfCreator.createFlyer()
构建并运行您的应用程序。 输入传单正文的标题和一些文本,然后点击预览。 看,您的PDF现在显示两种类型的文本!

您的下一个目标是让用户能够将图像添加到传单中。
Adding Images
启动项目允许用户从照片库或相机中选择图像。 所选图像可以是水平的或垂直的,并且可以是任何尺寸。 将图像添加到页面需要调整图像大小,同时保留图像的宽高比和方向。
首先,在PDFCreator的末尾添加以下方法:
func addImage(pageRect: CGRect, imageTop: CGFloat) -> CGFloat {
// 1
let maxHeight = pageRect.height * 0.4
let maxWidth = pageRect.width * 0.8
// 2
let aspectWidth = maxWidth / image.size.width
let aspectHeight = maxHeight / image.size.height
let aspectRatio = min(aspectWidth, aspectHeight)
// 3
let scaledWidth = image.size.width * aspectRatio
let scaledHeight = image.size.height * aspectRatio
// 4
let imageX = (pageRect.width - scaledWidth) / 2.0
let imageRect = CGRect(x: imageX, y: imageTop,
width: scaledWidth, height: scaledHeight)
// 5
image.draw(in: imageRect)
return imageRect.origin.y + imageRect.size.height
}
以下是此代码如何使图像适合页面。
- 1) 定义图像最多可以是页面高度的40%和页面宽度的80%。
- 2) 接下来,计算图像的最大宽度与实际宽度的比率,然后对高度执行相同的操作。您可以将这两个比率中较小的一个作为尺寸来调整图像大小。该比率最大化图像的大小,同时确保其符合约束条件。
- 3) 使用比率计算图像的缩放高度和宽度。
- 4) 计算水平偏移量以使图像居中,就像之前使用标题文本一样。使用您计算的大小在此坐标处创建一个矩形。
- 5) 在
UIImage上使用draw(in :)绘制图像。此方法缩放图像以适合矩形。最后,将图像底部的坐标返回给调用者,就像使用标题文本一样。
您将在标题和正文之间插入图像以满足传单设计。在createFlyer()中,用以下内容替换对addBodyText(pageRect:textTop :)的调用:
let imageBottom = addImage(pageRect: pageRect, imageTop: titleBottom + 18.0)
addBodyText(pageRect: pageRect, textTop: imageBottom + 18.0)
接下来,您需要将图像传递给PDFCreator。 打开FlyerBuilderViewController.swift并将prepare(for:sender :)的实现替换为:
if
let title = flyerTextEntry.text,
let body = bodyTextView.text,
let image = imagePreview.image {
let pdfCreator = PDFCreator(title: title, body: body,
image: image, contact: "")
vc.documentData = pdfCreator.createFlyer()
}
构建并运行应用程序,您应该在页面上看到您的图像。 尝试不同大小和方向的照片,您可以看到代码如何使它们适合页面。

Drawing Graphics
传单通常包括底部的撕掉区域,这样读者可以随身携带的联系信息。 您的下一步将添加该功能到传单。
你将分两步实施撕下功能。 首先,您将在页面上添加线条以分隔撕下标签。 然后,您将联系人信息添加到每个选项卡。
首先在PDFCreator的末尾添加一个新方法。
// 1
func drawTearOffs(_ drawContext: CGContext, pageRect: CGRect,
tearOffY: CGFloat, numberTabs: Int) {
// 2
drawContext.saveGState()
// 3
drawContext.setLineWidth(2.0)
// 4
drawContext.move(to: CGPoint(x: 0, y: tearOffY))
drawContext.addLine(to: CGPoint(x: pageRect.width, y: tearOffY))
drawContext.strokePath()
drawContext.restoreGState()
// 5
drawContext.saveGState()
let dashLength = CGFloat(72.0 * 0.2)
drawContext.setLineDash(phase: 0, lengths: [dashLength, dashLength])
// 6
let tabWidth = pageRect.width / CGFloat(numberTabs)
for tearOffIndex in 1..<numberTabs {
// 7
let tabX = CGFloat(tearOffIndex) * tabWidth
drawContext.move(to: CGPoint(x: tabX, y: tearOffY))
drawContext.addLine(to: CGPoint(x: tabX, y: pageRect.height))
drawContext.strokePath()
}
// 7
drawContext.restoreGState()
}
- 1) 这种新方法需要几个参数。首先是绘制图形上下文(稍后详细介绍),然后是页面的矩形。您还可以传递选项卡顶部的位置以及要创建的选项卡数量。
- 2) 您保存图形上下文的当前状态。稍后,您将恢复上下文,撤消两次调用之间所做的所有更改。此配对可在每个步骤开始时保持环境一致。
- 3) 然后代码将描边线的宽度设置为两个点。
- 4) 接下来,在传递的高度绘制从页面左侧到右侧的水平线,然后恢复之前保存的状态。
- 5) 保存当前上下文后,在选项卡之间绘制虚线垂直线。要在
Core Graphics中创建虚线,可以定义一个数组,其长度为交替的实线和空段。这里,数组将短划线和空格定义为0.2英寸长。 - 6) 要以磅为单位计算每个选项卡的宽度,可以将页面宽度除以选项卡数。接下来,循环并绘制每个选项卡之间的虚线。
- 7) 在循环内,您可以通过将制表符号乘以每行的宽度来计算分隔线的水平位置。然后从选项卡顶部绘制线条,在此处绘制水平线,到页面底部。
- 8) 绘制完所有线后,恢复图形状态。
您需要Core Graphics上下文传递给此方法。在UIGraphicsPDFRendererContext上使用cgContext来获取一个。
为此,请转到createFlyer()并在addBodyText(pageRect:textTop :)之后添加以下代码:
let context = context.cgContext
drawTearOffs(context, pageRect: pageRect, tearOffY: pageRect.height * 4.0 / 5.0,
numberTabs: 8)
构建并运行应用程序。 输入传单的标题,正文和图像,然后点击预览。 你应该看到页面底部的撕下线。
你仍然需要自己切割虚线。 应用程序无法完成所有操作。

所以你有撕下的标签,但它们仍然是空白的。 在下一步中,您将向标签添加联系信息。
Adding Rotated Text
当然,您希望文本在拉出标签的长边上运行,因此您需要旋转文本。 为此,请打开PDFCreator.swift并将以下方法添加到类的末尾:
func drawContactLabels(
_ drawContext: CGContext,
pageRect: CGRect, numberTabs: Int) {
let contactTextFont = UIFont.systemFont(ofSize: 10.0, weight: .regular)
let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.alignment = .natural
paragraphStyle.lineBreakMode = .byWordWrapping
let contactBlurbAttributes = [
NSAttributedString.Key.paragraphStyle: paragraphStyle,
NSAttributedString.Key.font: contactTextFont
]
let attributedContactText = NSMutableAttributedString(
string: contactInfo,
attributes: contactBlurbAttributes
)
// 1
let textHeight = attributedContactText.size().height
let tabWidth = pageRect.width / CGFloat(numberTabs)
let horizontalOffset = (tabWidth - textHeight) / 2.0
drawContext.saveGState()
// 2
drawContext.rotate(by: -90.0 * CGFloat.pi / 180.0)
for tearOffIndex in 0...numberTabs {
let tabX = CGFloat(tearOffIndex) * tabWidth + horizontalOffset
// 3
attributedContactText.draw(at: CGPoint(x: -pageRect.height + 5.0, y: tabX))
}
drawContext.restoreGState()
}
此方法是用于将正文文本添加到PDF的过程的扩展。要使文本垂直向上运行,请使用旋转变换(rotation transform)。旋转会更改您确定布局的方式。以下是旋转文本引起的更改:
- 1) 您使用
size()来查找在当前上下文中绘制字符串所需的最小大小。旋转交换绘制文本中的水平和垂直元素。因此,您可以使用文本的高度来确定偏移以使文本在选项卡中居中,而不是宽度。 - 2) 您想要逆时针旋转文本90度。用负角度变换指示逆时针方向。
Core Graphics期望以弧度指定的角度。 - 3) 旋转也会影响坐标系,如下图所示。该旋转改变轴的方向和坐标增加的方向。原点未移动时,您可以交换X和Y值,因为X坐标现在向下缩小页面,Y坐标在页面右侧增加。

将以下行添加到createFlyer()的末尾以绘制联系信息:
drawContactLabels(context, pageRect: pageRect, numberTabs: 8)
您需要将联系信息发送到PDFCreator。 打开FlyerBuilderViewController.swift和 - 最后一次 - 用以下代码替换prepare(for:sender :)的实现:
guard
segue.identifier == "previewSegue",
let vc = segue.destination as? PDFPreviewViewController,
let title = flyerTextEntry.text,
let body = bodyTextView.text,
let image = imagePreview.image,
let contact = contactTextView.text
else {
return
}
let pdfCreator = PDFCreator(
title: title,
body: body,
image: image,
contact: contact
)
vc.documentData = pdfCreator.createFlyer()
构建并运行您的应用,输入所有字段的信息,然后点击预览。 你应该看到最终的PDF。

您的应用程序会创建一个PDF,但它并没有被困在应用程序中。 因此,在下一步中,您将添加将PDF共享到应用程序的功能。
Sharing the PDF
打开FlyerBuilderViewController.swift并将shareAction()的内容替换为:
// 1
guard
let title = flyerTextEntry.text,
let body = bodyTextView.text,
let image = imagePreview.image,
let contact = contactTextView.text
else {
// 2
let alert = UIAlertController(
title: "All Information Not Provided",
message: "You must supply all information to create a flyer.",
preferredStyle: .alert
)
alert.addAction(UIAlertAction(title: "OK", style: .default, handler: nil))
present(alert, animated: true, completion: nil)
return
}
// 3
let pdfCreator = PDFCreator(
title: title,
body: body,
image: image,
contact: contact
)
let pdfData = pdfCreator.createFlyer()
let vc = UIActivityViewController(
activityItems: [pdfData],
applicationActivities: []
)
present(vc, animated: true, completion: nil)
在这里你:
- 1) 首先,确保用户添加了传单的所有信息。
- 2) 如果没有,则创建提示消息,将其显示给用户并返回。
- 3) 如果用户已添加传单的所有信息,则创建PDF。 然后创建一个
UIActivityViewController来提供和显示共享对象的数据。
构建并运行应用程序,输入所有信息,然后点击应用程序右下角的“共享”。 您将看到共享PDF文件的选项。 不幸的是,模拟器没有提供许多有用的选项,因此您可能希望在真实设备上运行该应用程序。

One Final Touch
在共享PDF之前进行的检查是一个很好的用户界面功能。 因此,现在您将添加一个检查,以确保在用户请求预览时所有信息都存在。
打开FlyerBuilderViewController.swift文件,并在prepare(for:sender)上面,添加这个新方法以确定是否应该发生segue:
override func shouldPerformSegue(withIdentifier identifier: String,
sender: Any?) -> Bool {
if
let _ = flyerTextEntry.text,
let _ = bodyTextView.text,
let _ = imagePreview.image,
let _ = contactTextView.text {
return true
}
let alert = UIAlertController(
title: "All Information Not Provided",
message: "You must supply all information to create a flyer.",
preferredStyle: .alert
)
alert.addAction(UIAlertAction(title: "OK", style: .default, handler: nil))
present(alert, animated: true, completion: nil)
return false
}
此代码检查用户是否在每个text field中输入了内容并选择了图像。如果是这样,它允许segue。如果没有,它会显示错误消息并停止segue。
在本教程中,您构建了一个使用PDFKit创建PDF文件的应用程序。用户的输入会生成一个传单,您可以与其他iOS应用程序共享。在此过程中,您学习了如何创建PDF,使用Core Text和Core Graphics并共享创建的文档。
有关PDFKit的更多信息,请查看Apple的PDFKit Documentation和 Introducing PDFKit on iOS — WWDC 2017会议。
后记
本篇主要讲述了基于PDFKit的PDF文档的创建和分享,感兴趣的给个赞或者关注~~~
