本文主要介绍一下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"];
}
复制代码