最近有个朋友想做一个pdf预览,要求能够上下滑动翻页、带缩放、目录跳转功能。

因为之前我只做过简单的预览,那时直接用uiwebview实现的,这次找了下资料,发现一个比较好的库。

其原理实现:

自定义uiview来显示pdf+使用的是苹果官方的api读取目录+uiscrollview实现缩放及翻页。

不过这个库是左右翻页的,我不是很习惯,就改成了上下滑动翻页,并且在底部添加了页码显示(1/10格式)。

效果图如下:

其中几段核心代码:

1、加载pdf文件

CFURLRef pdfURL = CFBundleCopyResourceURL(CFBundleGetMainBundle(), (__bridge CFStringRef)@"002.pdf", NULL, NULL);
pdfDocument = CGPDFDocumentCreateWithURL((CFURLRef)pdfURL);
CFRelease(pdfURL);

2、获取pdf文件目录

#pragma mark 获取pdf文件目录
- (NSArray *)getPDFContents: (CGPDFDocumentRef) myDocument
{ CGPDFDictionaryRef mycatalog= CGPDFDocumentGetCatalog(myDocument);
CommentNode *rootNode = [[CommentNode alloc] initWithCatalog:mycatalog];
CommentNode *rootOutlineNode = [rootNode childrenForName:@"/Outlines"];
CommentNode *pagesNode = [rootNode childrenForName:@"/Pages"];
NSArray *pagesArray = [self getPagesFromPagesNode:pagesNode];
CommentNode *destsNode = [rootNode childrenForName:@"/Dests"]; return [self getContentsForOutlineNode:rootOutlineNode pages:pagesArray destsNode:destsNode];
} - (NSArray *)getContentsForOutlineNode:(CommentNode *)rootOutlineNode pages:(NSArray *)pagesArray destsNode:(CommentNode *)destsNode
{
NSMutableArray *outlineArray = [[NSMutableArray alloc] init];
CommentNode *firstOutlineNode = [rootOutlineNode childrenForName:@"/First"];
CommentNode *outlineNode = firstOutlineNode;
while (outlineNode) {
NSString *title = [[outlineNode childrenForName:@"/Title"] value];
CommentNode *destNode = [outlineNode childrenForName:@"/Dest"];
NSMutableDictionary *outline = [NSMutableDictionary dictionaryWithDictionary:@{@"Title": title}];
int index = ;
if (destNode) {
if ([[destNode typeAsString] isEqualToString:@"Array"]) {
CGPDFObjectRef dest = (__bridge CGPDFObjectRef)[[[destNode children] objectAtIndex:] object];
index = [self getIndexInPages:pagesArray forPage:dest];
} else if ([[destNode typeAsString] isEqualToString:@"Name"]) {
NSString *destName = [destNode value];
CGPDFObjectRef dest = (__bridge CGPDFObjectRef)[[[[[destsNode childrenForName:destName] childrenForName:@"/D"] children] objectAtIndex:] object];
index = [self getIndexInPages:pagesArray forPage:dest];
}
} else {
CommentNode *aNode = [outlineNode childrenForName:@"/A"];
if (aNode) {
CommentNode *dNode = [aNode childrenForName:@"/D"];
if (dNode) {
CommentNode *d0Node = [[dNode children] objectAtIndex:];
if ([[d0Node typeAsString] isEqualToString:@"Dictionary"]) {
CGPDFObjectRef dest = (CGPDFObjectRef)[d0Node object];
index = [self getIndexInPages:pagesArray forPage:dest];
}
}
}
}
[outline setObject:@(index) forKey:@"Index"];
NSArray *subOutlines = [self getContentsForOutlineNode:outlineNode pages:pagesArray destsNode:destsNode];
[outline setObject:subOutlines forKey:@"SubContents"];
[outlineArray addObject:outline];
outlineNode = [outlineNode childrenForName:@"/Next"];
}
return outlineArray;
} - (NSArray *)getPagesFromPagesNode:(CommentNode *)pagesNode
{
NSMutableArray *pages = [NSMutableArray new];
CommentNode *kidsNode = [pagesNode childrenForName:@"/Kids"];
for (CommentNode *node in [kidsNode children]) {
NSString *type = [[node childrenForName:@"/Type"] value];
if ([type isEqualToString:@"/Pages"]) {
NSArray *kidsPages = [self getPagesFromPagesNode:node];
[pages addObjectsFromArray:kidsPages];
} else {
[pages addObject:node];
}
}
return pages;
} - (int)getIndexInPages:(NSArray *)pages forPage:(CGPDFObjectRef)page
{
for (int k = ; k < pages.count; k++) {
CommentNode *node = [pages objectAtIndex:k];
if ([node object] == page)
return k+;
}
return ;
}

源码获取:https://github.com/TangledHusky/YJ-PDFReader/tree/master

特别鸣谢:

参考文献:https://blog.csdn.net/shenshucong520/article/details/51578695

iOS实现pdf文件预览,上下翻页、缩放,读取pdf目录的更多相关文章

  1. Vue PDF文件预览vue-pdf

       最近做项目,遇到预览PDF这个功能,在网上找了找,大多推荐的是pdf.js,不过在Vue中还是想偷懒直接npm组件,最后找到了一个还不错的Vue-pdf 组件,GitHub地址:https:// ...

  2. java 文件转成pdf文件 预览

    一.前端代码 //预览功能 preview: function () { //判断选中状态 var ids =""; var num = 0; $(".checkbox& ...

  3. PDF文件预览和下载

    背景:项目中实现pdf文件的预览以及下载 环境:jdk1.8.SpringBoot2.0.Maven    PDF.js下载地址将下载的源码拷入项目中    修改viewer.js: 将default ...

  4. 利用 ICEpdf 快速实现 pdf 文件预览功能

    之前工作中,需要实现一个在线预览pdf的功能,一开始用的的 jQuery-media 插件来实现的,后来感觉有点慢,就继续寻找更好的替代品,直到遇见了 ICE pdf... ICEpdf (官网:ht ...

  5. vue中如何实现pdf文件预览?

    今天产品提出一个优化的需求,就是之前我们做的图片展示就是一个img标签搞定,由于我们做的是海外后台管理系统,那边的人上传的文件时pdf格式,vue本事是不支持这种格式文件展示的,于是就google搜索 ...

  6. 实战动态PDF在线预览及带签名的PDF文件转换

    开篇语: 最近工作需要做一个借款合同,公司以前的合同都是通过app端下载,然后通过本地打开pdf文件,而喜欢创新的我,心想着为什么不能在线H5预览,正是这个想法,说干就干,实践过程总是艰难的,折腾了3 ...

  7. 动态PDF在线预览

    实战动态PDF在线预览及带签名的PDF文件转换 开篇语: 最近工作需要做一个借款合同,公司以前的合同都是通过app端下载,然后通过本地打开pdf文件,而喜欢创新的我,心想着为什么不能在线H5预览,正是 ...

  8. 关于pc端 app端pdf,word xls等文件预览的功能

    第一种用H5标签<iframe>标签实现 返回的文件类型,文件流,文件流返回必须在设置 contentType对应的Mime Type, 返回文件的物理位置. 已经实测可以支持的文件类型 ...

  9. Office在线预览及PDF在线预览的实现方式史上最全大集合

    Office在线预览及PDF在线预览的实现方式大集合 一.服务器先转换为PDF,再转换为SWF,最后通过网页加载Flash预览 微软方:利用Office2007以上版本的一个PDF插件SaveAsPD ...

随机推荐

  1. 用sql的avg(score)求完平均值后,保存两位小数的方法(用于查询或视图)

    查jx_score表的平均值,以哪次考试(testid)和科目分组(courseid) select testid, courseid, round(avg(`jx_score`.`score`),2 ...

  2. 用面向对象重写thread 实现多次调用一个线程

    思路: 利用thread类中,run方法在子线程中调用,其他方法在主线程调用,所以将生产者写入主线程,将消费者写入run函数中在子线程中执行,完成生产者消费者模型 注意: 1. 要在 init 函数中 ...

  3. redis虚拟内存

    对于redis 这样的内存数据库, 内存总是不够用的. 除了可以将数据分割到多个 redis 服务器以外. 另外的能够提高数据库容量的办法就是使用虚拟内存技术把那些不经常访问的数据交换到磁盘上 如果我 ...

  4. HDU 5178 pairs【二分】||【尺取】

    <题目链接> 题目大意: 给定一个整数序列,求出绝对值小于等于k的有序对个数. 解题分析: $O(nlong(n))$的二分很好写,这里就不解释了.本题尺取$O(n)$也能做,并且效率很不 ...

  5. 一个完整的Java程序示例

    (1) 第一个程序HelloWorld: package mypack; //相当于一个目录 public class HelloWorld{ public static void main(Stri ...

  6. 利用nginx,腾讯云免费证书制作https

    之前一直在研究,https怎么弄.最近看到了腾讯云提供的免费得ssl证书,寻思把网站弄成https. 首先先去腾讯云购买一个免费得证书. 点击后填写内容, 然后下载证书 解压证书就可以看到,提供四种方 ...

  7. SQL varbinary varchar 互转

    --============================================== -- FUNCTION varbin2hexstr -- 将 varbinary 类型的数据转换为 v ...

  8. Codeforces.209C.Trails and Glades(构造 欧拉回路)

    题目链接 \(Description\) 给定一张\(n\)个点\(m\)条边的无向图,允许有自环重边.求最少加多少条边后,其存在从\(1\)出发最后回到\(1\)的欧拉回路. 注意,欧拉回路是指要经 ...

  9. DevC++出现[Error] ld returned 1 exit status,如何解决才好呢?

    回答: 代码在vc中没问题,虽然没用过DevC++. 可以把 ld returned 1 exit status前面的详细出错说出来程序是没有问题的,可能的问题最有可能是以下2个1.是你的程序已经在运 ...

  10. [UOJ282]长度测量鸡

    思路: 数学归纳. 设最少所需刻度数为$s$,则$n和s$的关系为: $n=1,s=0;$ $n=2,s=1;$ $n=3,s=3;$ ... 观察发现$s=n(n-1)/2$,得到$sn$时,满足条 ...