前言
2017年夏天,在蘋果全球開發(fā)者大會(WWDC)上魏身,蘋果公司終于推出了針對于 iOS 的 PDFKit 支持压语。PDFKit 自從 MacOS 10.4 以來一直在 AppKit for MacOS 中。但 UIKit 卻遲遲得不到支持押袍,盡管蘋果公司之前在 iBooks 和 Mail 中使用過 PDFKit 引颈, 但是該框架并未向開發(fā)人員開房耕皮。
PDFKit 包含了大量關于 PDF 相關的功能,例如蝙场,打開凌停,修改,繪圖和保存 PDF 售滤,也包含了搜索文本罚拟。在 iOS 11 后,蘋果終于開放了 PDFKit 完箩。目前(雖然離 PDFKit 發(fā)布已經(jīng)過了一年多)赐俗,但是目前中文資料和 Demo 確實比較少,下面筆者就帶著大家簡單的了解一下 PDFKit弊知。
核心功能
主要核心功能如下:
PDFView
- 用于顯示 PDF 阻逮,包括選擇的內(nèi)容,導航秩彤,縮放等功能叔扼。
PDFDocument
- 表示允許您寫入、搜索和選擇PDF數(shù)據(jù)的PDF數(shù)據(jù)或文件漫雷。
PDFPage
- 呈現(xiàn)PDF數(shù)據(jù)瓜富,添加注釋,獲取頁面文本等等珊拼。
PDFAnnotation
- PDF 中的附加內(nèi)容,包括注釋流炕、鏈接澎现、表單等。
實現(xiàn)一個簡單的 PDF 閱讀器
讓我看到你們的雙手每辟, put your hands up!
創(chuàng)建 PDFView
引入 #import <PDFKit/PDFKit.h>
剑辫,創(chuàng)建 PDFView ,創(chuàng)建之前渠欺,首先要創(chuàng)建 PDFDocument 妹蔽,這里通過文件路徑 URl 進行創(chuàng)建。
NSString *pdfPath = [[NSBundle mainBundle] pathForResource:@"swift" ofType:@"pdf"];
NSURL *pdfUrl = [NSURL fileURLWithPath:pdfPath];
PDFDocument *docunment = [[PDFDocument alloc] initWithURL:pdfUrl];
創(chuàng)建 PDFView ,將 PDFDucument 對象賦給 PDFView胳岂。
self.pdfView = [[PDFView alloc] initWithFrame:self.view.bounds];
self.pdfView.document = docunment;
self.pdfView.autoScales = YES;
self.pdfView.userInteractionEnabled = YES;
self.pdfView.backgroundColor = [UIColor grayColor];
至此编整,就實現(xiàn)了 PDF 的讀取及顯示。
創(chuàng)建 PDFThumbnail
- PDF 縮略圖的創(chuàng)建
首先獲取 PDFDocument 的屬性 PDFPage :
// Returns a PDFPage object representing the page at index. Will raise an exception if index is out of bounds. Indices
// are zero-based.
- (nullable PDFPage *)pageAtIndex:(NSUInteger)index;
通過 PDFPage 的對象方法乳丰,可以獲取 PDF 的縮略圖掌测,這里需傳入圖片的 size:
// Convenience function that returns an image of this page, with annotations, that fits the given size.
// Note that the produced image is "size to fit": it retains the original page geometry. The size you give
// may not match the size of the returned image, but the returned image is guaranteed to be equal or less.
- (PDFKitPlatformImage *)thumbnailOfSize:(PDFSize)size forBox:(PDFDisplayBox)box PDFKIT_AVAILABLE(10_13, 11_0);
創(chuàng)建 collectionViewCell ,通過 collectionView 就可以實現(xiàn)一個大致的功能产园。
點擊跳轉(zhuǎn)
獲取 cell 的點擊事件汞斧,取出所點擊的 PDFPage 對象,用下述方法進行跳轉(zhuǎn):
// Scrolls to page.
- (void)goToPage:(PDFPage *)page;
獲取 PDF 的大綱 PDFOutline
PDFOutline 是一個層級關系的對象什燕,他表示 PDF 的大綱(也就是我們常用的書簽)粘勒。每個 PDFOutline 對象都可通過 childAtIndex:
方法獲取出他的孩子對象,注意
屎即,這里需要先判斷 numberOfChildren
庙睡,以確定該 outline 對象存在多少個孩子節(jié)點,避免下標超界引發(fā)的崩潰剑勾。
實現(xiàn)大綱功能
從 PDFDocument 中獲取 PDFOutline
PDFOutline *outline = self.document.outlineRoot;
遍歷 outline 孩子節(jié)點(默認只遍歷一層)
- (void)setOutlineRoot:(PDFOutline *)outlineRoot
{
_outlineRoot = outlineRoot;
for (int i = 0; i < outlineRoot.numberOfChildren; i++)
{
PDFOutline *outline = [outlineRoot childAtIndex:i];
outline.isOpen = NO;
[self.arrData addObject:outline];
}
[self.tableView reloadData];
}
當點擊節(jié)點時埃撵,判斷有無孩子節(jié)點,進行當前數(shù)組的新增或刪除虽另。
插入節(jié)點
這里只添加孩子節(jié)點中一層暂刘,不進行遞歸操作。
- (void)insertOulineWithParentOutline:(PDFOutline *)parentOutline
{
NSInteger baseIndex = [self.arrData indexOfObject:parentOutline];
for (int i = 0; i < parentOutline.numberOfChildren; i++)
{
PDFOutline *tempOuline = [parentOutline childAtIndex:i];
tempOuline.isOpen = NO;
[self.arrData insertObject:tempOuline atIndex:baseIndex + i + 1];
}
}
刪除節(jié)點
首先判斷該節(jié)點下有無孩子節(jié)點捂刺,若無直接返回谣拣;
判斷每個孩子節(jié)點是否還存在孩子節(jié)點,若有族展,則進行遞歸操作逐一進行刪除森缠。
注意
:此處是為了點擊回收父節(jié)點時將該父節(jié)點下的所有子節(jié)點(不論層級)全部刪除。
- (void)removeOutlineWithParentOuline:(PDFOutline *)parentOutline
{
if (parentOutline.numberOfChildren <= 0)
{
return;
}
for (int i = 0; i < parentOutline.numberOfChildren; i++)
{
PDFOutline *node = [parentOutline childAtIndex:i];
if (node.numberOfChildren > 0 && node.isOpen)
{
[self removeOutlineWithParentOuline:node];
NSInteger index = [self.arrData indexOfObject:node];
if (index)
{
[self.arrData removeObjectAtIndex:index];
}
}
else
{
if ([self.arrData containsObject:node])
{
NSInteger index = [self.arrData indexOfObject:node];
if (index)
{
[self.arrData removeObjectAtIndex:index];
}
}
}
}
}
判斷節(jié)點深度仪缸,一遍設置顯示偏移量
- (NSInteger)findDepthWithOutline:(PDFOutline *)outline
{
NSInteger depth = -1;
PDFOutline *tempOutline = outline;
while (tempOutline.parent != nil)
{
depth++;
tempOutline = tempOutline.parent;
}
return depth;
}
實現(xiàn) PDF 搜索功能
這里搜索功能主要靠下述方法實現(xiàn)
// Begins a find, searching the document for string. Search results are handled via a
// PDFDocumentDidFindMatchNotification or if the delegate implements -[didMatchString:]. Supported options are:
// NSCaseInsensitiveSearch, NSLiteralSearch, and NSBackwardsSearch.
- (void)beginFindString:(NSString *)string withOptions:(NSStringCompareOptions)options;
調(diào)用此方法之前贵涵,首先需將 PDFDocument 設置代理,通過 PDFDocument 的代理進行回調(diào)恰画。獲取 PDFSelection 對象宾茂,
#pragma mark - --- PDFDocument Delegate ---
- (void)didMatchString:(PDFSelection *)instance
{
[self.arrData addObject:instance];
[self.tableView reloadData];
}
再根據(jù) selection 對象顯示搜索內(nèi)容。
PDF 縮放功能
調(diào)用下述方法即可對 PDFView 進行縮放拴还,
// Zooming changes the scaling by root-2.
- (IBAction)zoomIn:(nullable id)sender;
@property (nonatomic, readonly) BOOL canZoomIn;
- (IBAction)zoomOut:(nullable id)sender;
@property (nonatomic, readonly) BOOL canZoomOut;
實現(xiàn)雙擊縮放或還原:
這里通過設置 pdfView 的 scaleFactor 屬性即可實現(xiàn)跨晴,注意
:scaleFactorForSizeToFit
屬性是當前 PDF 充滿屏幕的比例。
- (void)doubleTapAction
{
if (self.pdfView.scaleFactor == self.pdfView.scaleFactorForSizeToFit)
{
[UIView animateWithDuration:0.2 animations:^{
self.pdfView.scaleFactor = self.pdfView.scaleFactorForSizeToFit * 4;
}];
}
else
{
[UIView animateWithDuration:0.2 animations:^{
self.pdfView.scaleFactor = self.pdfView.scaleFactorForSizeToFit;
}];
}
}
Demo
GitHub : https://github.com/japho/PDFDemo
本文作者:Japho
本文原地址:https://japho.top/2018/11/21/guideline-of-pdfkit/
未經(jīng)本人同意請勿擅自轉(zhuǎn)載片林,轉(zhuǎn)載請注明出處端盆。