版本记录
版本号 | 时间 |
---|---|
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文档的创建和分享,感兴趣的给个赞或者关注~~~