通过基线对齐多个SKLabelNodes [英] Align multiple SKLabelNodes by Baseline

查看:100
本文介绍了通过基线对齐多个SKLabelNodes的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个SKLabelNodes的集合.每个节点代表一个单词的字母.每个节点都是SKSpriteNode的子级. spriteNode上具有显式的高度([text sizeWithAttributes:@{NSFontAttributeName : font}];返回的高度),并且宽度与labelNode相同.

labelNode然后位于spriteNode内部的中心,并具有verticalAlignmentMode = SKLabelVerticalAlignmentModeBaseline.在稍后的阶段,我将需要在每个字母上设置背景图像(将使用spriteNode完成).为了进行测试,我使用了单色,使问题显而易见:

如您所见,字母"y"的下部显示在容器spriteNode的下面. 'g'和其他字母也会发生相同的情况.我还应该解释一下,每个letterNode(即spriteNode和子级labelNode)在垂直方向上居中,并在另一个SKSpriteNode内水平隔开,用于包含一个单词的所有字母.

创建letterNode的代码:

SKLabelNode *labelNode = [SKLabelNode labelNodeWithText:text];
labelNode.fontName = font.fontName;
labelNode.fontSize = font.pointSize;
labelNode.fontColor = colour;
labelNode.position = CGPointMake(0, -floor(height/2));
// height is the same explicit height used to create the spriteNode.

SNLetterNode *letter = [SNLetterNode spriteNodeWithColor:[UIColor lightGrayColor] size:CGSizeMake(labelNode.frame.size.width, height)];
letter.letter = text;
letter.labelNode = labelNode;
letter.size = CGSizeMake(self.labelNode.frame.size.width, height);

包含一个单词的所有字母的SKSpriteNode的创建方式如下:

CGSize fullWordSize = [text sizeWithAttributes:@{NSFontAttributeName : font}];

SNWordNode *word = [SNWordNode spriteNodeWithColor:[UIColor clearColor] size:fullWordSize];
word.letterNodes = letterNodes;
word.text = text;

我认为问题是由于我定位和/或调整labelspriteNodes大小的方式引起的.我尝试使用不同的verticalAlignmentModes,并根据此重新定位标签,但都无济于事.如果我知道一种基于文本基线对齐节点的方法,那将是一个开始.

我想发生的是,使灰色背景向下延伸,覆盖"y"的下部,并使其发生在 all letterNodes上(无论是否他们需要它,例如"y").而且文本仍然可以按基线对齐.

任何帮助将不胜感激,

谢谢.

解决方案

据Apple的说法,结果是,在边框下方出现的(在我的示例中)"y"部分称为降序". docs( https://developer.apple.com/library/ios/Documentation/StringsTextFonts/Conceptual/TextAndWebiPhoneOS/TypoFeatures/TextSystemFeatures.html ).

UIFont具有一个名为descender的属性,它为您提供了下降的最大值.我用它来增加包含SKLabelNodeSKSpriteNode的大小,并适当地将标签居中.

I have a collection of SKLabelNodes. Each node represents a letter of a word. Each node is the child of an SKSpriteNode. The spriteNodehas an explicit hight set on it (the hight returned by [text sizeWithAttributes:@{NSFontAttributeName : font}];), and has the same width as the labelNode.

The labelNode is then centred inside the spriteNode, and has verticalAlignmentMode = SKLabelVerticalAlignmentModeBaseline. At a later stage, I will need to set a background image on each letter (which will be done using the spriteNode). For testing purposes, I am using a solid colour, making the problem apparent:

As you can see, the lower part of the letter 'y' is showing bellow the container spriteNode. The same thing happens with 'g's and other letters. I should also explain that each letterNode (that is, the spriteNode and child labelNode) is centred vertically, and spaced out horizontally, inside another SKSpriteNode, used to contain all the letters for a word.

Code that creates the letterNode:

SKLabelNode *labelNode = [SKLabelNode labelNodeWithText:text];
labelNode.fontName = font.fontName;
labelNode.fontSize = font.pointSize;
labelNode.fontColor = colour;
labelNode.position = CGPointMake(0, -floor(height/2));
// height is the same explicit height used to create the spriteNode.

SNLetterNode *letter = [SNLetterNode spriteNodeWithColor:[UIColor lightGrayColor] size:CGSizeMake(labelNode.frame.size.width, height)];
letter.letter = text;
letter.labelNode = labelNode;
letter.size = CGSizeMake(self.labelNode.frame.size.width, height);

The SKSpriteNode that contains all the letters for a word is created like so:

CGSize fullWordSize = [text sizeWithAttributes:@{NSFontAttributeName : font}];

SNWordNode *word = [SNWordNode spriteNodeWithColor:[UIColor clearColor] size:fullWordSize];
word.letterNodes = letterNodes;
word.text = text;

I believe the problem is being caused by the way I am positioning and/or sizing the label and spriteNodes. I have tried using different verticalAlignmentModes, and repositioning the labels based on that, all to no avail. If I knew of a way to align the nodes based on the baseline of the text, that would be a start.

What I would like to happen, is for the grey background to extend down, covering the lower part of the 'y', and for that to happen on all letterNodes (regardless of whether they require it, like the 'y'). And for the text to still be aligned by baseline.

Any help would be much appreciated,

Thanks in advance.

解决方案

So it turns out, the part of the (in my example) 'y' that was appearing bellow the border is called a "descender", according to Apple's docs (https://developer.apple.com/library/ios/Documentation/StringsTextFonts/Conceptual/TextAndWebiPhoneOS/TypoFeatures/TextSystemFeatures.html).

UIFont has a property on it, called descender, and it gives you the highest value the descent can be. I used that to increase the size of the SKSpriteNode containing the SKLabelNode, and properly centre the label.

这篇关于通过基线对齐多个SKLabelNodes的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆