zoukankan      html  css  js  c++  java
  • iOS实现pdf文件预览,上下翻页、缩放,读取pdf目录

    最近有个朋友想做一个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 = 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"];
        }
        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 = 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

  • 相关阅读:
    回流与重绘
    事件循环的一些小啰嗦
    async与await的那些事儿
    数组去重的方法们
    Object的一些常用方法
    JS事件流的一些理解
    关于Ajax的那些记录
    call、bind与apply函数的区别
    继承的一些细碎记载
    计算机基础的小贴士(1)
  • 原文地址:https://www.cnblogs.com/yajunLi/p/9272610.html
Copyright © 2011-2022 走看看