最近有个朋友想做一个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://blog.csdn.net/shenshucong520/article/details/51578695