iOS 11 后苹果在iOS平台开放了PDFKit SDK,可以使用这个框架显示和操作 pdf 文件,此项目应用PDFKit实现显示pdf、显示缩略图、展开大纲和搜索文字的功能。
1、了解PDFKit框架的的类
部分 class 描述:
PDFView: 用来展示pdf
PDFThumbnailView: 用来展示一排缩略图
PDFDocument: 代表一个pdf文件
PDFPage: pdf中的页
PDFOutline: pdf的大纲目录
PDFSelection: pdf中的一段选择的文字,比如搜索的文字
PDFAnnotation: pdf注解
PDFAction: pdf跳转,比如说目录到页的跳转
PDFDestination: pdf 跳转目标,跳转页中使用
PDFBorder: 可选的注释边界
2、PDFDocument详解
PDFDocument代表一个pdf文件,这个类里面包含所有的文档的数据信息。包括pdf文件的页数、缩略图、大纲等数据信息,所有其他的类的都是围绕着这个核心来获取数据的。
@available(iOS 11.0, *)
open class PDFDocument : NSObject, NSCopying
PDFDocument的定义是继承NSObject的类,并且实现了NSCopying协议。
public init()
public init?(url: URL)
public init?(data: Data)
初始化的方式有这三种方式,使用url或者数据data的方式去创建文档的模型对象。
// 返回pdf文件的url
open var documentURL: URL? { get }
//这是PDFDocument与 CGPDFDocument的关联对象,通过这个对象可以调用很多CoreGraphics的API
open var documentRef: CGPDFDocument? { get }
// 以字典的形式返回元数据,例如作者、书名等
open var documentAttributes: [AnyHashable : Any]?
// PDF 文件的版本信息(例如: major version = 1, minor = 4; PDF v1.4).
open var majorVersion: Int { get }
open var minorVersion: Int { get }
@available(iOS 11.0, *)
open var allowsPrinting: Bool { get } // Printing the document
@available(iOS 11.0, *)
open var allowsCopying: Bool { get } // Extract content (text, images, etc.)
@available(iOS 11.0, *)
open var allowsDocumentChanges: Bool { get } // Modify the document contents except for page management (document attrubutes)
@available(iOS 11.0, *)
open var allowsDocumentAssembly: Bool { get } // Page management: insert, delete, and rotate pages
@available(iOS 11.0, *)
open var allowsContentAccessibility: Bool { get } // Extract content, but only for the purpose of accessibility
@available(iOS 11.0, *)
open var allowsCommenting: Bool { get } // Create or modify annotations, including form field entries
@available(iOS 11.0, *)
open var allowsFormFieldEntry: Bool { get } // Modify form field entries, even if allowsCommenting is NO
@available(iOS 11.0, *)
open var outlineRoot: PDFOutline?
// 文档的页数
open var pageCount: Int { get }
常用的一些属性。在这个类里面也有很多的方法对文档的页数、大纲、存储位置的一些操作,这里就不在啰嗦,详细请看API。
Demo:下面我们来做一个书架的功能,详细展示pdf文档的封面、作者、名称、简介等
// copy PDF文件到指定的文件
func copyPDFToDictionaryDirectory() {
let manager = FileManager.default
let docDirectory = manager.urls(for: .documentDirectory, in: .userDomainMask).first
let fileName = "swift.pdf"
if let PDFFile = Bundle.main.url(forResource: "swift", withExtension: ".pdf") {
let distination = docDirectory?.appendingPathComponent(fileName)
if !manager.fileExists(atPath: (distination?.path)!) {
try? manager.copyItem(at: PDFFile, to: distination!)
}
}
}
// 获取到pdf文件对象模型,在tableview中展示,此时展示的是pdf文件,类似书架上的一本书。
func getPDFFiles() {
let manager = FileManager.default
let docDirectory = manager.urls(for: .documentDirectory, in: .userDomainMask).first
let contents = try! manager.contentsOfDirectory(at: docDirectory!, includingPropertiesForKeys: nil, options: .skipsHiddenFiles)
self.PDFs = contents.flatMap({
PDFDocument(url: $0)
})
self.table.reloadData()
}
然后我们可以通过document.documentAttributes获得所有文档的属性信息
extension PDFDocumentAttribute {
@available(iOS 11.0, *)
public static let titleAttribute: PDFDocumentAttribute
@available(iOS 11.0, *)
public static let authorAttribute: PDFDocumentAttribute // NSString containing document author.
@available(iOS 11.0, *)
public static let subjectAttribute: PDFDocumentAttribute // NSString containing document title.
@available(iOS 11.0, *)
public static let creatorAttribute: PDFDocumentAttribute // NSString containing name of app that created document.
@available(iOS 11.0, *)
public static let producerAttribute: PDFDocumentAttribute // NSString containing name of app that produced PDF data.
@available(iOS 11.0, *)
public static let creationDateAttribute: PDFDocumentAttribute // NSDate representing document creation date.
@available(iOS 11.0, *)
public static let modificationDateAttribute: PDFDocumentAttribute // NSDate representing last document modification date.
@available(iOS 11.0, *)
public static let keywordsAttribute: PDFDocumentAttribute // NSArray of NSStrings containing document keywords.
}
这样我们就可以添加作者、书名等信息到书架上了。
如果我想获取pdf文档的封面缩略图怎么办。我们可以通过PDF文档的数据拿到第一页的缩略图作为封面
// 获取第一页的对象
let page = document.page(at: 0)
// 拿到第一页的缩略图
let thumbnail = page.thumbnail(of: CGSize(width: 40, height: 60), for: .cropBox)
到此书架的功能基本完成。
3、PDFView
书架的功能已经完完成,那么怎么去战术书里面的内容里,框架为我们提供了展示的视图层PDFView,下面来看看这个类是如何使用的吧。
// 第一个属性就是获取pdf文档对象,获取文档之后PDFView就可以加载文档里面的内容,从而展示在屏幕上。
open var document: PDFDocument?
下面我们看看一些常用的属性的设置
pdfView.autoScales = true
pdfView.displayMode = .singlePage
pdfView.displayDirection = .horizontal
pdfView.usePageViewController(true, withViewOptions: [UIPageViewControllerOptionInterPageSpacingKey: 20])
pdfView.addGestureRecognizer(pdfViewGestureRecognizer)
pdfView.document = pdfDocument
最后我们只需要将这个view addsubview就可以展示文档的内容了
PDFView有很多的api可以操作文档例如滚动到上一页、下一页、获取当前页等
// 滚动到第一页
@IBAction open func goToFirstPage(_ sender: Any?)
// 滚动到最后一页
@IBAction open func goToLastPage(_ sender: Any?)
// 滚动到下一页
@IBAction open func goToNextPage(_ sender: Any?)
//滚动到前一页
@IBAction open func goToPreviousPage(_ sender: Any?)
@IBAction open func goBack(_ sender: Any?)
@IBAction open func goForward(_ sender: Any?)
// 当前页
open var currentPage: PDFPage? { get }
// 滚动到指定页
open func go(to page: PDFPage)
// 这个方法回去刷新view的布局,文字会重新排版,类似layoutSubViews()
open func layoutDocumentView()
现在pdf文档展示的部分就完成了。