创建自定义文本绘图视图

时间:2009-05-10 06:32:59

标签: iphone objective-c cocoa-touch

我正在为iPhone创建一个语法高亮显示器,为了显示多种格式的文本,我对UIView进行了分类并修改了drawRect:方法,以便显示每一行并使用正确的语法高亮显示(突出显示)使用RegEx提前完成,一次用CGContextShowTextAtPoint()一行绘制文本。一切正常,我将每行文本存储为NSMutableArray中的NSString,我通过隐藏的UITextField及其委托方法处理键盘,光标是一个闪烁的CALayer,可以通过触摸移动,我有一个自定义滚动视图处理滚动。但是,我有两个问题似乎无法解决这个问题:

  1. 自动换行,现在文本只是离开屏幕的左端。为了保持快速,我只重新绘制已更改的视图部分(通常只是正在编辑的行,但有时候下面的行也是如此,例如,如果按下文档的中途返回)setNeedsDisplayInRect:。这使得自动换行很复杂,因为你必须在屏幕上绘制多行,即使它仍然只是数组中的一个对象。

  2. UIViews的最大内容大小为1024x1024,相当于大约64行。我需要能够显示更多。我正在考虑一个接一个地使用多个CALayers,但我在向图层绘制内容时遇到问题(使用drawLayer:inContext:drawInContext:)。

  3. 所以我的问题是:

    • 对于如何完成这两点中的任何一点,是否有人有任何甚至一般的建议。或者,
    • 是否有人已经编写了一个自定义文本绘图视图来处理我可以使用的这些内容。

    谢谢,

    凯尔

    编辑:滚动问题已经解决了,但是我仍然遇到自动换行问题。我的麻烦是一切都是按行完成的:视图一次更新一行,文本存储为行数组,荧光笔一次突出显示一行,等等,并在数组中有一个索引(一行文本行)在屏幕上占用多行会引发一些问题,例如,我必须实现自己的可移动光标,当你移动光标时,它需要能够转动一条显示行(通过将touch.x划分为行高度)到文本行(数组中的索引)。有什么想法吗?

3 个答案:

答案 0 :(得分:1)

您应该首先花一些时间了解如何在Mac上解决此问题:

http://developer.apple.com/documentation/Cocoa/Conceptual/TextArchitecture/Tasks/AssembleSysByHand.html

http://developer.apple.com/documentation/Cocoa/Conceptual/TextLayout/TextLayout.html

特别是,您应该熟悉行片段生成,这是您尝试为自动换行解决的问题,并且您应该了解字形生成以便很好地执行富文本。当然,您不需要实现NSTypesetter或NSLayoutManager的所有灵活性,但Mac上的文本系统非常强大,您应该从它的示例中学习。为iPhone实现类似于NSAttributedString的东西可能对您有价值并提高您的表现。

除非你正在移动很多东西(这在UIScrollView中最适合),我认为你不应该在这里使用CALayers。对于这个问题来说,这似乎有些过分,实际上可能会对UIScrollView已经提供的优化产生负面影响。如果您发现性能问题,请首先确保您没有在drawRect中进行冗余计算:。

答案 1 :(得分:1)

查看Three20 library中的TTStyledText。不确定它与你的目标有多好,但可能会以你为例。 (图书馆本身有点臃肿,但是看起来很棒。)

答案 2 :(得分:0)

最好在UIView中托管的CATiledLayer中绘制文本,以便绕过1024x1024纹理大小限制(在所有现有设备上实际上看起来实际上是2048x2048)。有关CALayer中文本绘制的示例,我将引用您CPTextLayer框架内的Core Plot类。该层(继承自同一框架内的CPLayer类)在CALayer中进行跨平台(Mac和iPhone)文本呈现。您可以将其扩展为CATiledLayer以用于更长的文本块。

需要注意的一件事是,在此层中使用特定于平台的drawAtPoint:方法,而不是您正在使用的CGContextShowTextAtPoint()函数。原因是CGContextShowTextAtPoint()仅适用于ASCII文本,这意味着您无法使用它进行Unicode文本渲染。有一个使用CGContextShowTextAtPoint()在renderAsVectorInContext:方法底部的#defig'd out部分内绘制文本的示例。