本文主要介紹一下iOS加載PDF的方法。git
使用webView加載是最簡單的方式,這是最大的優勢,使用方便,而且能夠加在網絡文件,缺點就是效果體驗不怎麼好,單一的上下滑動效果。github
注意:web
UIWebview組件已經在今年被apple禁用,使用webView沒法提交App Store,本文下面使用的都是基於WKWebView
。objective-c
首先看一下 webView加載的方法,markdown
該方法第一個參數URL自不用說,是咱們想要加載的文件的路徑,注意看apple的解釋,這是一個file URL
,咱們應該使用下面這個方法的結果做爲參數。網絡
NSURL *fileUrl = [NSURL fileURLWithPath:@"path"];
複製代碼
第二個參數readAccessURL,是用來傳入頁面引用資源的路徑,正常是前面File URL
的上級目錄,備註也寫的很詳細,若是該參數傳入的是單一的文件,那麼只有這個文件能被WebKit加載。app
若是出現了PDF亂碼的狀況,使用下面這個方法進行加載:框架
[self.wkWebView loadData:data MIMEType:@"application/pdf" characterEncodingName:@"GBK" baseURL:fileUrl];
複製代碼
使用QLPreviewController須要導入QuickLook框架oop
#import <QuickLook/QuickLook.h>
複製代碼
遵循QLPreviewControllerDelegate和QLPreviewControllerDataSource,動畫
使用方式以下:
@property (nonatomic, strong) QLPreviewController *previewController;
複製代碼
- (QLPreviewController *)previewController {
if (!_previewController) {
_previewController = [[QLPreviewController alloc] init];
_previewController.delegate = self;
_previewController.dataSource = self;
}
return _previewController;
}
複製代碼
實現協議:
/// 返回文件數量
- (NSInteger)numberOfPreviewItemsInPreviewController:(QLPreviewController *)controller {
return 1;
}
- (id<QLPreviewItem>)previewController:(QLPreviewController *)controller previewItemAtIndex:(NSInteger)index {
NSString *pdfPath = [[NSBundle mainBundle] pathForResource:@"test" ofType:@"pdf"];
return [NSURL fileURLWithPath:pdfPath];
}
複製代碼
還有一種方式是使用UIDocumentInteractionController進行預覽,效果與QLPreviewController同樣,可是不支持多文件預覽。
使用時也須要遵循UIDocumentInteractionControllerDelegate。
- (UIViewController *)documentInteractionControllerViewControllerForPreview:(UIDocumentInteractionController *)controller {
return self;
}
- (UIView*)documentInteractionControllerViewForPreview:(UIDocumentInteractionController*)controller {
return self.view;
}
- (CGRect)documentInteractionControllerRectForPreview:(UIDocumentInteractionController*)controller {
return self.view.frame;
}
複製代碼
UIDocumentInteractionController繼承於NSObject,而非UIViewController,使用該類自帶的presentPreviewAnimated方法展現。
這兩種的加載方法優點是,
集成方便,而且自帶系統分享功能
QLPreviewController支持多文件預覽
劣勢的話就是體驗比較差,與webView相似的上下滑動的預覽方式
若是咱們須要一個比較好的體驗效果,相似於翻書同樣的動畫效果,這個時候咱們就須要使用CGContexDrawPDFPage來進行本身繪製。
獲取PDF文件
/// 獲取路徑
CFStringRef path = CFStringCreateWithCString(NULL, filePath.UTF8String, kCFStringEncodingUTF8);
CFURLRef url = CFURLCreateWithFileSystemPath(NULL, path, kCFURLPOSIXPathStyle, NO);
/// 獲取PDF
CGPDFDocumentRef document = CGPDFDocumentCreateWithURL(url);
/// 主動釋放
CFRelease(path);
CFRelease(url);
複製代碼
獲取PDF頁數
NSInteger totoalPages = CGPDFDocumentGetNumberOfPages(document);
複製代碼
獲取頁數內容
CGPDFPageRef page = CGPDFDocumentGetPage(document, _currentPage);
複製代碼
獲取當前頁的大小
CGRect rect = CGPDFPageGetBoxRect(page, kCGPDFMediaBox);
複製代碼
繪製當前頁內容
- (void)drawRect:(CGRect)rect {
CGContextRef context = UIGraphicsGetCurrentContext();
[[UIColor whiteColor] set];
CGContextFillRect(context, rect);
/// 轉換座標系
CGContextTranslateCTM(context, 0.0, rect.size.height);
CGContextScaleCTM(context, 1.0, -1.0);
CGPDFPageRef page = CGPDFDocumentGetPage(document, _currentPage);
CGAffineTransform pdfTransform = CGPDFPageGetDrawingTransform(page, kCGPDFCropBox, rect, 0, true);
CGContextConcatCTM(context, pdfTransform);
CGContextDrawPDFPage(context, page);
}
複製代碼
最後一步加上翻頁動畫
/// 返回上一頁
[self transitionWithType:@"pageUnCurl" subtype:kCATransitionFromRight];
/// 下一頁
[self transitionWithType:@"pageCurl" subtype:kCATransitionFromRight];
複製代碼
- (void)transitionWithType:(NSString *)type subtype:(CATransitionSubtype)subType {
CATransition *animation = [CATransition animation];
/// 設置動畫時長
animation.duration = 0.8;
/// 設置動畫樣式
/***
使用CATransitionType
kCATransitionPush 推入效果
kCATransitionMoveIn 移入效果
kCATransitionReveal 截開效果
kCATransitionFade 漸入漸出效果
或者直接使用如下字符串:
cube 方塊
suckEffect 三角
rippleEffect 水波抖動
pageCurl 上翻頁
pageUnCurl 下翻頁
oglFlip 上下翻轉
cameraIrisHollowOpen 鏡頭快門開
cameraIrisHollowClose 鏡頭快門開
*/
animation.type = type;
/// 設置動畫方向
/**
kCATransitionFromRight 從右邊
kCATransitionFromLeft 從左邊
kCATransitionFromTop 從上面
kCATransitionFromBottom 從下面
*/
if (subType) {
animation.subtype = subType;
}
/// 動畫的速度
/** CAMediaTimingFunction:
kCAMediaTimingFunctionLinear 勻速
kCAMediaTimingFunctionEaseIn 慢進快出
kCAMediaTimingFunctionEaseOut 快進慢出
kCAMediaTimingFunctionEaseInEaseOut 慢進慢出 中間加速
kCAMediaTimingFunctionDefault 默認
*/
animation.timingFunction = [CAMediaTimingFunction functionWithName: kCAMediaTimingFunctionEaseIn];
[self.layer addAnimation:animation forKey:@"animation"];
}
複製代碼