最近有個朋友想做一個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