【BUG】3.8.2中使用scheduleOnce会导致node.hasChangedFlags异常

prefab中放入一个editbox来观察这个bug

const node = instantiate(this.prefab);
this.scheduleOnce(() => {
    node.parent = this.node;
})

会发现点击editbox后,输入框位置不对,根源是node中这个逻辑存在问题

/**
* @en Whether the node's transformation have changed during the current frame.
* @zh 这个节点的空间变换信息在当前帧内是否有变过?
*/
get hasChangedFlags (): number {
    return this._flagChangeVersion === globalFlagChangeVersion ? this._hasChangedFlags : 0;
}

this._flagChangeVersion与globalFlagChangeVersion不想等,导致edit-box-impl中的更新逻辑没有执行。

public update (): void {
    const node = this._delegate!.node;
    if (!node.hasChangedFlags) {
        return;
    }
    this._updateMatrix();
}

如果将scheduleOnce换成setTimeout,可以恢复正常

const node = instantiate(this.prefab);
setTimeout(() => {
    node.parent = this.node;
})

@jare

3赞

看这个东西的逻辑感觉是加入帧验证 ,不是这一帧的更新不处理

是的,这是因为很多节点的更新都在editbox,update之后。后面我已经修复了,不调用update了,使用afterUpdate的时候,在更新dom的坐标。

https://github.com/cocos/cocos-engine/pull/16768

合并后有个另外的问题,弹窗有两个输入框A和B,AB节点在同一个layout下,其中A节点显示、B节点隐藏,当弹窗缩放打开时,A输入框触发后位置是对的。然后显示B节点,首次触发B输入框的选中,位置是错位的,再次触发输入框选择位置才是正确的。 @king668

这个场景我测试过,之前有这个问题,但是我验证的时候是没有问题。 不过layout的更新与editbox的更新可能有关系。

你可以弄个demo我看看,我看看跟我的测试例有啥区别

EditboxDemo.zip (21.0 KB)
刚看到消息,这个可以试试