一、setContentSize与setDimensions对于Label的作用
1、首先看看setContentSize的定义:
/*
* Set the untransformed size of the node.
* 设置节点转换前的大小
* The contentSize remiains the same no matter the node is scaled or rotated.
* 无论缩放还是旋转节点,它的contentSize始终保持不变
* All nodes has a size. Layer and Scene has the same size of the screen.
* 所有的节点都有一个大小,layer和scene的大小和屏幕大小保持一致
*/
/*
* 说明:
* 1、节点在使用的过程中可能进行缩放、旋转等变化,这样导致我们看见的节点的大小可能发生了变化。但是
* contentSize是一直保持
* 不变的,因为这是一个基准。可以想一下,如果这个contentSize在进行缩放之后发生了变化,那么在
* setScale(1.5f)之后再设置setScale(1.0f)如何能够还原呢?
*/
void Node::setContentSize(const Size& size)
{
if(!size.equals(_contentSize)
{
_contentSize = size;
_anchorPoints.set(_contentSize.width * _anchorPoint.x, _contentSize.height * _anchorPoint.y);
_transformUpdated= _transformDiry = _inverseDirty = _contentSizeiryt = true;
}
}
2、其次,我们看看setDimenSions的定义:
/*
Sets the untransformed size of the Label in a more efficient way.
以一种更高效的方式设置Label未转换前的大小
*/
void Label::setDimensions(float width, float height)
{
if(_overflow == Overflow::RESIZE_HEIGHT){
height = 0;
}
if (height != _labelHeight || width != _labelWidth)
{
_labelWidth = width;
_labelHeight = height;
_labelDimensions.width = width;
_labelDimensions.height = height;
_maxLineWidth = width;
_contentDirty = true;
if(_overflow == Overflow::SHRINK){
if (_originalFontSize > 0) {
this->restoreFontSize();
}
}
}
}
3、_labelDimensions、_labelWidth、_labelHeight的使用:
? ? ? ? 在setDimensions的源码中我们看到了主要是对这几个成员变量进行了设置,那么这几个成员变量的使用方法以及相关的作用是什么呢?首先来看看_labelDimensions的使用:
? ? ? ? ?从上图中可以知道,对于_labelDimensions成员变量的使用只在相关的set和get方法中出现了。接下来我们看看_labelWidth和_labelHeight的使用。
? ? ? ??
? ? ? ? 从上图中我们可以看到,在alignText方法中使用到了_labelWidth,即在文字的对齐方式中进行了使用。因此我们很自然的可以想到:_labelDimenSions与标签的对齐方式有关。其中setMaxLineWidth也说明了,只有在调用了setDimenSions方法之后,对于标签的对齐方式、显示方式才会生效。?
4、实验验证:
auto labTest = Label::createWithSystmeFont("I love China, I am a Chinese", "", 30);
labTetst->setPosition(Vec2(_size.width / 2, _size.height * 0.75f));
this->addChild(labTest, 100);
auto labTest2 = Label::createWithSystemFont("I love China, I am a Chinese", "", 30);
labTest2->setPosition(Vec2(m_vSize.width / 2, m_vSize.height * 0.70));
labTest2->setDimensions(200.0f, 80.0f);
this->addChild(labTest2, 100);
auto labTest3 = Label::createWithSystemFont("I love China, I am a Chinese", "", 30);
labTest3->setPosition(Vec2(m_vSize.width / 2, m_vSize.height * 0.65));
labTest3->setContentSize(Size(200.0f, 80.0f));
this->addChild(labTest3, 100);
? ? ? ? 由上述的实验结果我们可以看到,分别使用setDimenSions和setContentSize方法对于Label进行同样大小的设置,但是setContentSize并没有起到什么效果;而使用setDimenSions对Label的设置产生了效果,同时使其进行了自动缩放和换行的调整。
5、结论:
-
setContentSize和setDimenSions都是设置节点大小,但是对于Label而言,setContentSize并没有什么作用,而是通过使用setDimenSions来进行相关的设置。 -
对于Label进行对齐方式、换行等设置也只有在调用了setDimenSions之后才会生效。??
二、 Label常用操作封装
1、Label设置下划线:
? ? ? ? 在公司做产品的过程中遇到这样一个使用场景,需要对Label创建的字体加上一个下划线,但是又没有现成的接口可以设置下划线于是就自己封装了一个。
// Label增加下划线处理
void whStartLayer::labAttachUnderline(Label* labNode)
{
if (nullptr == labNode) {
return;
}
float labWidth = labNode->getContentSize().width;
auto underLine = DrawNode::create();
underLine->drawSegment(Vec2(0, 0), Vec2(labWidth, 0), 1, Color4F::BLACK);
labNode->addChild(underLine);
return;
}
示例1:
// 创建一个label
auto labPrivacy = Label::createWithSystemFont(u8"隐私协议", "", 40.0f);
labPrivacy->setTextColor(Color4B(0x2e, 0x2e, 0x2e, 0xff));
labPrivacy->setPosition(Vec2(visibleSize / 2));
this->addChild(labPrivacy);
// label增加下划线处理
labAttachUnderline(labPrivacy);
2、Label文本过长的处理方式
? ? ? ? 目前我在游戏开发的过程中经常会遇见文本内容过长的问题,我个人对于此类问题的处理主要是采用以下两种方式:1,设置label的最大宽度,不进行换行操作,当文本大小超过了最大宽度限定就会进行自动缩放;2,设置label的最大宽度,同时保持字体大小不变,超过最大限度之后之后进行换行处理。
? ? ? ? 对于第一种处理方式主要适用于标题、按钮文本等内容的处理,文本必须在一行呈现出来才比较美观。
// 标签内容一行呈现,字体进行自动缩放
void setLabAlignInOneLine(Label* labNode, float maxWidth)
{
auto curSize = labNode->getContentSize();
float dimenWidth = curSize.width > maxWidth ? maxWidth : curSize.width;
labNode->setDimensions(dimenWidth, curSize.height);
labNode->setOverflow(Label::Overflow::SHRINK); // 设置溢出处理方式(共有4种):缩放处理
labNode->setAlignment(TextHAlignment::CENTER, TextVAlignment::CENTER);
return;
}
? ? ? ? 对于第二种方式,我们保持字体的大小不变,在最大宽度限定下来自动适应高度。其实Label中的溢出处理方式中有一个“Label::Overflow::RESIZE_HEIGHT”,但是设置这个属性之后去获取标签的大小时,高度始终时0,因为这个bug我就放弃了这种处理方式。因为我在使用的过程中还是需要Label的大小去设置相应的位置坐标,因此我采用以下的方式进行处理。
? ? ? ? 使用过程中自己去判断为了保持字体大小不变,最大宽度限定下实际创建的Label会有多少行,然后手动去设定标签的大小。如果不手动设置标签大小的话,换行之后的部分文本可能无法显示出来。
void setLabAutoHeight(Label * labNode, float maxWidth, TextHAlignment hType, TextVAlignment vType, float lineSpace)
{
auto curSize = labNode->getContentSize();
int lineNum = (int)(curSize.width / maxWidth) + 1;
float dimenHeight = lineNum*(curSize.height + lineSpace) - lineSpace;
labNode->setDimensions(maxWidth, dimenHeight);
labNode->setAlignment(hType, vType);
labNode->setLineBreakWithoutSpace(true);
labNode->setLineSpacing(lineSpace);
return;
}
示例2:
// 示例代码:
string textStr = u8"这是一个标题示例,我们正在做溢出处理测试。";
auto labTemp = Label::createWithSystemFont(textStr, "", 40.0f);
labTemp->setPosition(Vec2(visibleSize.width / 2, 1000.0f));
labTemp->setTextColor(Color4B::BLACK);
this->addChild(labTemp);
auto labTemp2 = Label::createWithSystemFont(textStr, "", 40.0f);
labTemp2->setPosition(Vec2(visibleSize.width / 2, 900.0f));
labTemp2->setTextColor(Color4B::BLACK);
this->addChild(labTemp2);
setLabAlignInOneLine(labTemp2, 600.0f);
???
示例3:
// 示例代码:
// 文本内容一行展示
string textStr = u8"这是一个标题示例,我们正在做溢出处理测试。再继续增加一点文字长度!";
auto labTemp = Label::createWithSystemFont(textStr, "", 40.0f);
labTemp->setPosition(Vec2(visibleSize.width / 2, 900.0f));
labTemp->setTextColor(Color4B::BLACK);
this->addChild(labTemp);
// 水平居中对齐
auto labTemp2 = Label::createWithSystemFont(textStr, "", 40.0f);
labTemp2->setPosition(Vec2(visibleSize.width / 2, 700.0f));
labTemp2->setTextColor(Color4B::BLACK);
this->addChild(labTemp2);
setLabAutoHeight(labTemp2, 600.0f, TextHAlignment::CENTER, TextVAlignment::CENTER, 0.0f);
// 水平左对齐
auto labTemp3 = Label::createWithSystemFont(textStr, "", 40.0f);
labTemp3->setPosition(Vec2(visibleSize.width / 2, 500.0f));
labTemp3->setTextColor(Color4B::BLACK);
this->addChild(labTemp3);
setLabAutoHeight(labTemp3, 600.0f, TextHAlignment::LEFT, TextVAlignment::CENTER, 0.0f);
// 水平右对齐
auto labTemp4 = Label::createWithSystemFont(textStr, "", 40.0f);
labTemp4->setPosition(Vec2(visibleSize.width / 2, 300.0f));
labTemp4->setTextColor(Color4B::BLACK);
this->addChild(labTemp4);
setLabAutoHeight(labTemp4, 600.0f, TextHAlignment::RIGHT, TextVAlignment::CENTER, 0.0f);
?
三、Label常用接口说明:
- setLineBreakWithoutSpace();
指定当一行太长的时候对于标签来说会发生什么,该行会在单词之间自动进行断开换行,即标签太长而换行的时候不会将一个完成的单词一分为二。 - setMaxLineWith();
使标签最多不超过该行的未转换宽度,如果该值不为零,则标签的最大线宽将用于强制换行。即限制标签的最大宽度,如果超出之后会进行换行处理。 - setDimensions();
设置标签的大小,前面已经说过了,只要设置了标签的大小之后对于标签的自动换行、缩放、对齐方式等的设置才会有意义。 - setOverflow();
设置标签的移除处理方式,主要有四种处理方式:自动适应、超出区域被裁剪、自动缩放、自动适应高度的方式。 - setAlignment();
设置标签的对其方式,横向、纵向 - setLineSpacing();
设置标签的行距,不支持系统字体
?????????????????????
|