最近有個朋友想作一個pdf預覽,要求可以上下滑動翻頁、帶縮放、目錄跳轉功能。node
由於以前我只作過簡單的預覽,那時直接用uiwebview實現的,此次找了下資料,發現一個比較好的庫。git
其原理實現:github
自定義uiview來顯示pdf+使用的是蘋果官方的api讀取目錄+uiscrollview實現縮放及翻頁。web
不過這個庫是左右翻頁的,我不是很習慣,就改爲了上下滑動翻頁,而且在底部添加了頁碼顯示(1/10格式)。api
效果圖以下:iview
其中幾段核心代碼:ui
一、加載pdf文件spa
CFURLRef pdfURL = CFBundleCopyResourceURL(CFBundleGetMainBundle(), (__bridge CFStringRef)@"002.pdf", NULL, NULL); pdfDocument = CGPDFDocumentCreateWithURL((CFURLRef)pdfURL); CFRelease(pdfURL);
二、獲取pdf文件目錄.net
#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/mastercode
特別鳴謝:
參考文獻:https://blog.csdn.net/shenshucong520/article/details/51578695