情况:我有一个包含超链接的 pdf 文档。我希望我的 iPhone 应用程序能够显示此 pdf 文档,并允许单击超链接。
注意:目前,我正在尝试使用 UIWebView 来执行此操作,不幸的是,它似乎无法检测链接点击。有一个类的家庭&我在文档中读到过名为 CGPDF 的方法。该文档讨论了所有关于解析 pdf 文档以及不解析的内容,但没有具体说明如何检测链接点击以及不解析的内容(感谢苹果)。
The Situation: I have a pdf document that includes hyperlinks. I would like my iPhone app to display this pdf document, and enable clicking of the hyperlinks.
Note: Currently, I am trying to do this with a UIWebView, which unfortunately seems unable to detect link taps. There is a family of classes & methods called CGPDF which I have read about in the documentation. The documentation talks all about parsing pdf documents and what not but is not specific on how to detect link taps and what not (thanks apple).
发布评论
评论(1)
我无法评论 UIWebView,但 CGPDF 的东西是 CoreGraphics 的一部分。所以它主要用于绘图 - 您将有一个 PDF 对象和一个上下文来绘制它(几乎肯定是通过 UIView 的自定义子类接收的)并要求它以一定的比例和位置进行绘制。如果您是 CoreGraphics 和/或自定义 UIView 子类的新手,那么可能需要一天左右的时间才能了解它,但最坏的情况下也只有几百行。
CoreGraphics 对用户交互一无所知,所以我认为 Apple 认为这隐含着那里没有点击的概念,因此 CoreGraphics 无法直接帮助您捕获点击。
本文档。 CoreGraphics 在 OS X 和 iOS 上是相同的,只是初始坐标系的方向相反。在 OS X 上,它与 PDF 的方式相同,在 iOS 上则相反,因此如果未进行其他调整,PDF 将沿 y 反转渲染。示例显示代码后面的部分标题为“为 PDF 页面创建变换”,应该对此有所帮助 - 您只需要应用一个反转 y 的变换。
这里有一个关于如何创建的教程自定义 UIView 子类,包含一些 CoreGraphics 绘制步骤。
关于捕捉水龙头,事情变得有点复杂。由于文件格式的工作方式,您无需执行完整 PDF 检查之类的操作。链接的内容被绘制为外观,但它们应该按照 CoreGraphics 可以为您处理的正常 PDF 操作进行外观。然后有单独的表格描述用于捕获点击的边界框矩形以及它们应该转到的链接。这些表被 CoreGraphics 解析为易于阅读的格式,但未经检查。因此,您拥有所有工具来查找链接的位置,而无需了解太多有关文件格式的信息,但您仍然需要自己寻找它们。
相关的 CoreGraphics 构造是 CGPDFDictionary。您可以在此处获取最新的 PDF 规范,但 99%它与您无关,也不涵盖 CoreGraphics 已经实现的内容。您需要来回浏览文档,将所有内容拼凑在一起,但您可以跳到第 488 页上有关注释的第 8.4 节。
它最终会成为相当复杂的代码位组合,我可以'出于商业原因,我不会发布我自己的内容,但您需要建立页面名称到页码的映射,遍历链接注释(指向指定页面的链接)并执行一些操作来捕获点击。就我个人而言,我只是添加了不可见的 UIButtons 作为我的自定义 PDF 视图的子视图。显然,您应用于 PDF 的任何转换也需要应用于注释坐标。
总共大概有 1,000 行。
I can't comment on UIWebView, but the CGPDF stuff is part of CoreGraphics. So it's primarily for drawing — you'll have a PDF object and a context to draw it to (almost certainly received via a custom subclass of UIView) and ask it to draw at a certain scale and position. If you're new to CoreGraphics and/or custom UIView subclasses then it might take a day or so to get into it, but it'll end up being a few hundred lines at worst.
CoreGraphics doesn't know anything about user interaction, so I think Apple considered it implicit that there's no concept of taps down there, and hence no way that CoreGraphics can directly help you with catching taps.
There's example code for loading a PDF and drawing it to a context at the top of this document. CoreGraphics is the same on OS X and iOS, except that the initial coordinate system is the opposite way up. On OS X it is the same way around as a PDF, on iOS it's the opposite way, so PDFs will render inverted along y if otherwise unadjusted. The section directly after the example display code is entitled 'Creating a Transform for a PDF Page' and should help with that — you just need to apply a transform that inverts y.
There's a tutorial here on how to create a custom UIView subclass that includes some CoreGraphics drawing steps.
With respect to catching taps, things get a bit more complicated. You don't need to do anything like a full PDF inspection because of the way the file format works. Things that are links are drawn to look however they should look per the normal PDF operations that CoreGraphics can handle for you. There are then separate tables that describe bounding box rectangles for catching taps and the links they should go to. Those tables are parsed into an easy to read format by CoreGraphics but not inspected. So you're given all the tools to find out where the links are without having to learn too much about the file format, but you still need to fish through for them yourself.
The relevant CoreGraphics construct is the CGPDFDictionary. You can grab the latest PDF specification here, but 99% of it isn't relevant to you or covers things that CoreGraphics already implements. You'll need to jump back and forth through the documentation to piece all the bits together, but you can leap in at section 8.4 on Annotations, on Page 488.
It ends up being a reasonably complicated combination of bits of code and I can't post my own for commercial reasons but you'll want to build up a mapping of page names to page numbers, traverse the link annotations (which are links to named pages) and do something to catch taps. Personally I just added invisible UIButtons as subviews of my custom PDF view. Obviously any transform you're applying to the PDF needs to be applied to the annotation coordinates too.
The total thing was maybe 1,000 lines.