2010-12-12 107 views
8

我正在构建一个显示PDF的iPad应用程序,我希望能够显示目录和让用户导航到相关页面。如何获取iOS(iPad)中的PDF目录(大纲)数据?

在这一点上,我已经投入了几个小时的研究,看起来PDFKit [iOS不支持],我唯一的选择是手动解析PDF元数据。

我已经看过几种解决方案,但他们都没有提及一点 - 如何将“大纲”元数据中的页面与项目的实际页码相关联。我用[偷窥工具]检查了我的PDF文档,并且可以在树中看到轮廓。

[此解决方案]帮助我找出如何导航Outline/A/S/D树以找到“Dest”对象,但它使用[self.pages indexOfObjectIdenticalTo:destPageDic]执行某种对象比较。我不明白。

我已阅读[从Adobe官方PDF规格],以及部分“12.3.2.3命名目的地”描述了一个大纲条目可以指向一个页面的方式:

而不是直接与被定义 表 151中所示的显式语法,可以通过名称对象 (PDF1.1)或字节字符串(PDF1.2)间接地指向目的地 。

而与此线,是完全无法理解我继续说:

该项的值应是 字典,其中每个键是一个 目的地名称和相应的 值是定义 目的地的数组,使用 表151中显示的语法,或具有D 条目(其值是这样的数组)的字典。

这是指366页,“12.3.2.2显式目标”,其中一个表描述一个页面:“在每种情况下,页是一个间接引用页对象”

所以是的结果CGPDFDocumentGetPage或CGPDFPageGetDictionary是“对页面对象的间接引用”?

我发现了一个讨论的[lists.apple.com上的线程]。 [此评论]意味着您可以比较给定页面的CGPDFPageGetDictionary对象的地址(内存中?),并将其与PDF元数据的“大纲”树中的页面进行比较。

但是,当我查看“大纲”树中页面对象的地址并将它们与地址进行比较时,它们绝不会相同。该线程中使用的行“TTDPRINT(@”​​%d =>%p“,k + 1,dict);”在内存中打印“dict”作为指针..没有理由相信返回的对象与返回其他地方的对象相同..他们会在内存中的不同位置!

我最后的希望是从苹果的命令行“outline”工具[本书中提到](作为[由此线程提出])查看源代码,但我无法在任何地方找到它。底线 - 是否有人对PDF概述如何工作有所了解,或者了解一些读取PDF概述的开放源代码(最好是objective-c)?

ARGG:我有各种各样的联系张贴在这里,但显然一个新用户只能发布一个链接在一个时间

回答

3

CGPDFDocumentGetPage的结果是一样的间接页面引用解决,当你大纲项目中的目的地。两者本质上都是字典,你可以使用==比较它们。当你有你想知道的页码CGPDFDictionaryRef,你可以做这样的事情:

CGPDFDocumentRef doc = ...; 
CGPDFDictionaryRef outlinePageRef = ...; 
for (int p=1; p<=CGPDFDocumentGetNumberOfPages(doc); p++) { 
    CGPDFPageRef page = CGPDFDocumentGetPage(doc, p); 
    if (page == outlinePageRef) { 
    printf("found the page number: %i", p); 
    break; 
    } 
} 

一个明确的目的地然而,这不是一个网页,但与第一元素的数组作为页面。其他元素是页面上的滚动位置等。

+0

这是一个很好的答案。你最终的目标应该是创建一个nsdictionary,其中包含title->页码的键/ val对。这将构成TOC。 – shawnwall 2011-02-01 19:35:37

+1

实际上,您无法直接将outlinePageRef与CGPDFPageRef进行比较,但您可以将其与“CGPDFPageGetDictionary(page)”进行比较。 – 0xced 2011-02-02 00:35:51