2010-06-13 123 views
7

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

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

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

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

我的第一个实现基于UIWebView。我只是将文档呈现为CSS,用于文本样式。但是我无法获得所需的文本选择行为(跨段落边界),并且无法从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文档真的很烂?

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

+0

我发现SDK文档非常好。你似乎正在一个SDK目前有点虚弱的领域工作。 – zoul 2010-06-13 18:57:29

+0

SDK文档非常适合通过连接一堆预先存在的组件来构建应用程序。但是开发自定义组件所需技术的文档对我来说似乎严重缺乏。 – benjismith 2010-06-13 20:17:03

+0

@benjismith 你好, 我也在研究这样的应用程序。我需要解析一个epub文件。你有什么想法吗?你是如何做分页的?我有多个Xhtml页面,我无法弄清楚,我该如何做分页?任何你的帮助将不胜感激。 谢谢 – 2010-07-03 05:47:34

回答

1

只有两个随机观察:

  • 你能负担得起创建分页界面? (而不是“无止境的滚动”。)它看起来像一个分页界面会更容易在系统资源。

  • UIActionBar实际上是UIMenuController类。界面有点奇怪,因为菜单是单身(跆拳道?),但我相信你会毫不费力地计算出来。

希望有所帮助。

+0

由于各种原因,我不认为分页界面适用于我的应用程序。但从概念上讲,分页界面几乎与我正在查找的内容完全相同:只渲染当前屏幕上的内容,在屏幕外流动时回收元素,并提供指示用户当前位置的可视指示器(例如滚动条)该文件。如果我将文档建模为段落的链接列表(具有已知尺寸),则应该做零散渲染的微小操作。但是,我如何挂入平台标准的滚动功能呢?这就是问题所在。 – benjismith 2010-06-13 20:14:14

+0

感谢您对UIMenuController名称的更正。我相应地更新了我的原始问题。 – benjismith 2010-06-13 20:19:29

1

这是一个潜在的解决方案,但我不知道它是否疯了。由于我对iPhone的发展还很陌生,这可能是一个很大的禁忌。

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

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

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

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

2

您的文档是否有除每个段落以外的语义组件?如果你已经有了一些章节或页面的概念,我建议你将其中的每一个渲染为一个独立的表格单元格。创建一个表格单元非常简单,它可以让你忘记你实际上正在查看一个UITableView。你所需要做的就是覆盖drawRect:和setSelected:并且setHighlighted:和tah dah!没有更多的细胞除法器,除非你想要它们。此外,你可以通过使用tableview作为基础来做一些漂亮的事情。如果您在UITableView中定义了各个部分,那么您可以在翻阅文档时使用滚动的漂亮标题。你可以做的另一件事是添加一个“跳转到部分”栏/一个书签菜单,这样你就不必在节的边界上提供选择。

海量复制粘贴块在系统上也会非常痛苦。此外,如果您经历了麻烦提供这些内容,您可能不想让别人很容易一次复制全部内容......(如果没有关于您的项目的更多具体信息,不能更多地关注这一思路)。

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

我建议你在SDK文档中查找UITableViewCell UITableViewDelegate和UITableViewDataSource,因为如果您选择使用此建议,这些页面将显着帮助。

+0

我忘了提及使用tableviews和完全潜入代表和数据源的想法,您可以创建一个非常棒的轮廓视图,以非常壮观的方式为文档中各节的外观添加动画。 – fbartho 2010-06-14 07:43:18

+0

有一件事对你熟悉如果你走这条路线非常重要,那就是tableviewcell重用模型,它主要通过dequeueReusableCellWithIdentifier来访问:以及相应的init方法。鉴于你的文件太大,你可能不想预渲染一切。 UITableViews通过缓存一些单元格视图帮助解决这个问题,并简单地将已经离开屏幕一段时间的单元格的内容替换为要在屏幕上滚动的单元格的内容。 – fbartho 2010-06-14 07:52:50

+0

如果您使用NSTextField子类来承载文本,您将能够获得所需的选择行为。 – fbartho 2010-06-14 08:40:03

0

的UIWebView的是一个很好的choise,但我们需要另一个应用程序预渲染页面percisely使用每个字体和每个样式表和存储rendring信息到数据库表:

chapter_id int主键,
startlocation INT,
结束位置INT,
字号INT(或stylesheetname字符串)

使用JavaScript,我们可以计算出有多少的话适合与滚动出来一个div。

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

希望这会有所帮助。