在iPad上呈现长文档

时间:2010-06-13 18:35:10

标签: iphone objective-c ipad core-text

我正在为iPad上的自定义文档格式实现具有突出显示/注释功能的文档查看器。这些文件有点长(100到200页,如果在纸上打印),我很难找到正确的方法。以下是要求:

1)基本的富文本样式:控制左/右边距。控制字体名称,大小,前景/背景颜色和行间距。大胆,斜体,下划线等。

2)选择和突出显示任意文本区域(不限于段落边界,如Safari / UIWebView)。

3)自定义剪切/复制/粘贴弹出窗口(UIMenuController)这是该应用程序的基本要求之一。

我的第一个实现是基于UIWebView。我只是将文档渲染为带有CSS的HTML文本样式。但我无法获得我想要的那种文本选择行为(跨越段落边界),并且无法从UIWebView中自定义UIMenuController。

所以我开始研究javascript方法,使用JQuery伪装设备文本选择行为来捕获触摸事件并动态修改DOM以更改所选文本区域的背景颜色。我构建了一个虚假的UIMenuController控件作为隐藏的DIV,定位它并在有活动选择区域时将其取消隐藏。

不要太破旧。

主要问题是它是SLOOOOOOOW。滚动浏览文档非常快捷,但动态更改DOM并不是很顺畅。另外,我无法弄清楚如何重新创建放大镜放大镜,因此我的假文本选择GUI与本机实现看起来并不完全相同。此外,我还没有实现javascript层和objective-c层之间的通信桥梁(应用程序的其余部分存在),但它正在形成一个巨大的麻烦。

所以我一直在关注CoreText,但网上有很少的例子。我花了一点时间学习这个简单的小演示:

http://github.com/jonasschnelli/I7CoreTextExample/

它展示了如何使用CoreText将NSAttributedText字符串绘制到UIView中。但它有自己的问题:它没有实现文本选择行为,并且它没有呈现UIMenuController,所以我不知道如何实现这一点。而且,更重要的是,它试图一次性绘制整个文档,对于长文档而言会显着降低性能。我的文档可以包含数千个段落,并且一次只能在屏幕上显示不到1%的文档。

从好的方面来说,这些文件已包含精确的格式信息。我知道每行文本的确切页面位置,所以我不需要布局引擎。

有谁知道如何使用CoreText实现这种视图?我理解一个完整的实现对于像这样的问题来说是过度的,但我正在寻找一个有一些基本要求的好的CoreText示例:

1)精确布局&格式化控件(使用我已经计算过的格式化指标和文本样式)。

2)任意选择文字。

3)自定义UIMenuController。

4)为屏幕外对象有效地回收资源。

当文本元素在屏幕外滚动时,我很乐意实现自己的回收,但这不需要重新实现UIScrollView吗?

我是iPhone开发的新手,并且仍然习惯于Objective-C,但我已经在其他语言(Java,C#,flex / actionscript等)工作了十多年,所以我我对自己完成工作的能力充满信心,只要我对iPhone SDK有更好的感觉,并为这样的东西提供常见的编码模式。它只是我,还是SDK文档确实很糟糕?

无论如何,谢谢你的帮助!

4 个答案:

答案 0 :(得分:2)

您的文档是否包含除每个段落之外的任何语义组件?如果您已经有一些部分或页面的概念,我建议您将每个部分或页面渲染为独立的表格单元格。创建一个让您忘记实际正在查看UITableView的表格单元非常简单。你需要做的只是覆盖drawRect:和setSelected:和setHighlighted:和tah dah!除非您需要,否则不再使用单元格分隔符。此外,您可以使用tableview作为基础来做一些漂亮的事情。如果你在UITableView中定义了部分,那么你可以有一个漂亮的标题,当你翻阅你的文档时它会滚动。您可以做的另一件事是添加“跳转到部分”栏/书签菜单,这样您就不必跨部门边界提供选择。

大量复制粘贴块在系统上也会非常痛苦。此外,如果您经历了提供此内容的麻烦,您可能不希望让某人一次性复制所有内容太容易...(如果没有更多关于项目的细节,则无法遵循这一思路)。

如果您确实想要提供复制粘贴选项,您可以为每个逻辑页面或部分添加按钮,以便用户方便地立即选择和复制整个部分。 (也许引用相关?)

我建议您在SDK文档中查找UITableViewCell UITableViewDelegate和UITableViewDataSource,因为如果您选择使用此建议,这些页面将非常有用。

答案 1 :(得分:1)

只是两个随机观察:

  • 您能负担得起创建分页界面吗? (与“无休止的滚动”相反。)看起来分页界面在系统资源上要容易得多。

  • UIActionBar实际上是UIMenuController类。界面有点奇怪,因为菜单是单身(wtf?),但我相信你可以毫不费力地搞清楚。

希望有所帮助。

答案 2 :(得分:1)

这是一个潜在的解决方案,但我不知道它是否疯了。由于我仍然对iPhone开发这么新,这可能是一个很大的禁忌。

无论如何,我有想法将文档的每个段落(我已经精确计算过的维度)渲染为UITableView中的单元格。由于UITableView已经具有细胞回收机制,因此我不必从头开始实施,并且文档可以任意长,而不会导致资源消耗问题。

当然,我想摆脱单元格之间的行分隔符,因为我希望UI看起来像文档而不是表格。

或许我可以将文档的每个页面(如典型的PDF,这是分页文档格式)渲染为表格单元格,并覆盖单元格分隔符图形看起来像页面边界...

但是可以摆脱表中的默认触摸行为,而是在表格单元格内容上实现文本选择吗?是否完全不可能实现跨越段落边界的文本选择(在多个表格单元格之间)?

答案 3 :(得分:0)

UIWebView是一个很好的选择,但是我们需要另一个应用程序来使用每种字体和每个样式表预先渲染页面,并将渲染信息存储到数据库表中:

chapter_id int主键,
startlocation int,
结束位置int,
fontsize int(或stylesheetname string)

使用JavaScript,我们可以通过滚动来计算div中适合的单词数。

UIWebView很好,因为它提供了丰富的内容,并且具有选择和突出显示行为。

希望这会有所帮助。