将多行文本拟合到动态大小更改节点中

时间:2016-09-19 12:27:52

标签: ios objective-c sprite-kit nsstring nsarray

多线自动输入文本框类(使用SKNode作为父级)基本上使用2个元素创建:

  • 一个充当文本框框架的SKSpriteNode&背景图像/纹理持有人。
  • 一个NSMutableArray,包含NSStrings的设定限制数量(行),每个NSStrings都有一个设定的字符长度。

修改此文本框类后,可以使用任何框架宽度&高度,我意识到我没有编程NSMutableArray来自动更改其内容,使其很好地适合背景节点(也涉及一些填充)。所以在这里我想知道如何做到这一点,因为NSString只能返回字符数而不是宽度&每个字符串的高度(点数可能有助于我以某种方式创建字符约束)。

现在,NSMutableArray使用每个NSString&的硬编码最大字符数。整个阵列的最大行数(它现在是5行,当达到该限制时,会创建一个新的"页面" /数组)。这迫使我每次更改背景节点框架大小时手动重新调整这些参数,这会破坏允许背景框架更改的类的目的。

事情是,我试图以这样的方式解决这个问题,当我在github上发布这个类时,我希望解决方案考虑任何fontName& fontSize的。

我有什么方法可以解决这个问题?

1 个答案:

答案 0 :(得分:2)

我做过类似的事情。对于你想要的东西,它并不是100%工作,但应该足够相似。它使用根节点,从那里,它将使用NSString数组构建多行文本,而SKLabelNode数组又将用于构建NSString

我将概述我的所作所为。我还应该说我只在设置新文本时运行它。换句话说,我不承担每帧导出信息的惩罚。只有一次。

一般步骤是:

  • 您将迭代文本字符串中的每个字符。注意我这样做是因为我的代码支持自动换行以及其他对齐功能。所以对我来说,我想要那种程度的控制。由于这只是在创作时才进行,我对开销很好。如果你不想自行换行,你可以随时创建一系列单词并从那里开始工作。
  • 当您遍历每个角色时,您将生成一系列线条。数组中的每一行都是适合您框架的线条。现在,让我们不要担心垂直约束。所以这里我们主要担心宽度。对于当前行,您迭代的每个字符都将添加到当前行。对于此潜在的字符串,您将使用为您的字体配置的sizeWithAttributes' s NSDictionary。例如,在我的代码中,NSFontAttributeName : [UIFont fontWithName:self.fontName size:self.size]包含: size = [line sizeWithAttributes:attributes]; if (size.width > maxTextWidth) { needNewline = YES; } 。这将用于检查宽度,如果宽度超过框架宽度,则超​​出线条。

因此代码可能类似于:

SKLabelNode
  • 如果您超出了一行,则需要确定是否自动换行。如果是,则可以将当前行(减去一个字符)添加到行数组中。如果没有,你可以删除当前行中的最后一个单词,然后将其添加到行数组中。
  • 棘手的部分是处理空格和处理非字包装溢出。我没有解决空白问题,但你需要在代码中考虑这个问题。此外,您还需要考虑前导像素等。

一旦你有了一系列的行,你就可以创建你的孩子func Convert(img image.Image) *image.RGBA { b := img.Bounds() rgba := image.NewRGBA(b) for y := b.Min.Y; y < b.Max.Y; y++ { for x := b.Min.X; x < b.Max.X; x++ { r32, g32, b32, _ := img.At(x, y).RGBA() c := color.RGBA{uint8(r32>>8), uint8(g32>>8), uint8(b32>>8), 255} rgba.SetRGBA(x, y, c) } } return rgba } 了。我将它们添加到根目录,这允许我将组移动到需要的任何位置。

这里的真正关键是线阵列生成。