Label 设置文本后立即获取高度
前言
在给文本赋值之后不会立即刷新文本内容,而是在下一帧进行渲染,导致你不能立即获取文本的高度。
# 一. 为什么
官方给出的解释是:
由于 label 中_updateRenderData
处理开销过大,导致没办法设置 string
的时候去触发更新,只能在渲染的时候才可以获取到正确的 size。目前可以自行在设置 label 所有属性后在执行一次 label._updateRenderData(true)
; 就能带当帧获取大小。
# 二. 解决方案
解决问题的思路:
- 首先查看官方提供的api
- 没有的话可以去论坛搜索一下相关问题
- 其次就是看一下引擎的源码,
这里有两种解决方案:
- 直接调用 label 里面的私有方法 进行强行更新渲染;
- 延时 0.1秒 后在进行获取文本的高度 和 后续逻辑处理;
# 三. 强行更新渲染
论坛上人说的方法在新版本中已经使用不了了。
看了下引擎源码: ~/core/components/CCLabel.js
:
onEnable () {
this._super();
// Keep track of Node size
this.node.on(cc.Node.EventType.SIZE_CHANGED, this._nodeSizeChanged, this);
this.node.on(cc.Node.EventType.ANCHOR_CHANGED, this.setVertsDirty, this);
this._forceUpdateRenderData();
}
可以看到 onLoad
函数里面 直接调用了一个私有函数, 根据定义的函数名 翻译过来就是 强行更新渲染数据.
所以在游戏源码中可以这么写:
let label = this.node.getChildeByName(cc.Label);
label.string = "123";
// 强行更新
label._forceUpdateRenderData();
// 处理后面逻辑
...
# 四. 延迟执行后续逻辑
this.label.string = '121212222222';
setTimeout(function () {
console.log('this.label.width:', this.label.width);
// 执行后续逻辑
}.bind(this), 100);
# 五. 总结
- 方法二的更安全, 因为方法一直接调用了label的私有方法,风险更高;
- 方法一更直观,没有那么多异步的写法;
- 方法一的用法没有问题,只是语义不合法,而且是引擎不想让你知道的方法;