Label 设置文本后立即获取高度

前言

在给文本赋值之后不会立即刷新文本内容,而是在下一帧进行渲染,导致你不能立即获取文本的高度。


# 一. 为什么

官方给出的解释是:

由于 label 中_updateRenderData 处理开销过大,导致没办法设置 string 的时候去触发更新,只能在渲染的时候才可以获取到正确的 size。目前可以自行在设置 label 所有属性后在执行一次 label._updateRenderData(true); 就能带当帧获取大小。

# 二. 解决方案

解决问题的思路:

  1. 首先查看官方提供的api
  2. 没有的话可以去论坛搜索一下相关问题
  3. 其次就是看一下引擎的源码,

这里有两种解决方案:

  1. 直接调用 label 里面的私有方法 进行强行更新渲染;
  2. 延时 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的私有方法,风险更高;
  • 方法一更直观,没有那么多异步的写法;
  • 方法一的用法没有问题,只是语义不合法,而且是引擎不想让你知道的方法;