iOS实现pdf文件预览,上下翻页、缩放,读取pdf目录

摘要:
最近,一位朋友想要制作pdf预览,这需要能够使用缩放和目录跳转功能上下滚动。因为我以前只做过一个简单的预览,它是直接用uiwebview实现的。这一次,我通过查找信息找到了一个好图书馆。但是,这个库会从左向右翻页。我不习惯。相反,我上下滑动页面,并在底部添加页码。

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

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

其原理实现:

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

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

效果图如下:

iOS实现pdf文件预览,上下翻页、缩放,读取pdf目录第1张iOS实现pdf文件预览,上下翻页、缩放,读取pdf目录第2张

其中几段核心代码:

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 = 0;
        if(destNode) {
            if ([[destNode typeAsString] isEqualToString:@"Array"]) {
                CGPDFObjectRef dest = (__bridge CGPDFObjectRef)[[[destNode children] objectAtIndex:0] 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:0] 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:0];
                    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"];
    }
    returnoutlineArray;
}
- (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];
        }
    }
    returnpages;
}
- (int)getIndexInPages:(NSArray *)pages forPage:(CGPDFObjectRef)page
{
    for (int k = 0; k < pages.count; k++) {
        CommentNode *node =[pages objectAtIndex:k];
        if ([node object] ==page)
            return k+1;
    }
    return 1;
}

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

特别鸣谢:

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

免责声明:文章转载自《iOS实现pdf文件预览,上下翻页、缩放,读取pdf目录》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇我希望有一套自己的房子谈谈网络协议 – HTTP协议下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

gcc 编译器参数

一、GCC编译过程 参考:http://hi.baidu.com/zengzhaonong/item/c00e079f500adccab625314f-------------------------------------    Pre-Processing   cpp        预处理    Compiling        ccl       ...

thinkphp3.2.3版本文件目录及作用

下载thinkphp3.2.3版本,解压缩后将文件夹名字改为thinkphp,然后放在www目录下,里面的文件夹和文件的名字和作用如下:(前面有Tab健的表示下一级,thinkphp是根目录) //thinkphp //Application//写的程序都放在这里面,默认里面什么都没有。当从浏览器输入入口文件并运行后,这个文件夹里面就会出现下面的文...

Hadoop实战实例

      Hadoop实战实例        Hadoop 是Google MapReduce的一个Java实现。MapReduce是一种简化的分布式编程模式,让程序自动分布到一个由普通机器组成的超大集群上并发执行。就如同java程序员可以不考虑内存泄露一样, MapReduce的run-time系统会解决输入数据的分布细节,跨越机器集群的程序执行...

cmd 下登陆ftp及相关操作

cmd 下登陆ftp及相关操作   2011-08-09 20:34:28|  分类: 小技巧|字号 订阅 一、举例 假设FTP地址为“ 61.129.83.39”(大家试验的时候不要以这个FTP去试,应该可能密码要改掉。)       1:“开始”-“运行”-输入“FTP”进去cmd界面       2.open 61.129.83.39       如...

Visual Studio 2008 中程序路径配置 .

Visual Studio 2008 环境变量的配置(改为:Visual Studio 2008 中程序路径配置 更合理) 在调试 Visual Studio 2008 程序时,经常有一些动态链接库(即 dll 文件)需要加载到工程里,这样才能依赖第三方库进行程序调试。 这些动态链接库,往往都是测试版本或是开发中的版本,或者会有若干个版本;这个时候,...

复制pdf文字出来是乱码的一种可能的解决方案

最近在处理一个pdf文件,是一个地图文件,上面带各种文字的标注,地图比较大,而且文字信息比较多而且分散。因为字体的问题,在我的windows电脑上虽然可以正常显示,但是复制出来的文字都是方块,而且对应的文字也不能搜索。 如果不能搜索,也不能复制文字,那么后续的处理会非常棘手。通过不懈的google和尝试,发现了用Adobe Pdf虚拟打印机(别的虚拟打印机...