HumanBreak/docs/guide/ui-faq.md
2025-03-13 19:38:39 +08:00

4.2 KiB
Raw Blame History

UI 常见问题

为什么我的 UI 不显示?

检查 UI 的纵深zIndex是否符合预期有没有被其他元素遮挡检查当前元素是否处于 hidden 状态。可以在控制台输入 logTagTree() 来输出当前的渲染树 xml 标签结构,会包含一些重要信息。

第二种可能性是你的元素处在了父元素范围之外,导致被裁剪掉。注意,transform 属性是对元素本身的变换,这也会导致元素本身的矩形范围发生变化,如果你的元素设置了缩放、旋转等,需要考虑此属性对位置的影响。

为什么我的元素 onClick 事件没办法触发?

可能你的元素被纵深更高的元素覆盖,导致事件无法传播至你的元素,考虑在纵深更高的元素上添加 noevent 标识来禁用它的事件传播。注意,一个纯透明的元素也可能会覆盖你的元素,仔细查看你的渲染树结构。

第二种可能性是其子元素拦截了冒泡或是其父元素拦截了捕获,检查 e.stopPropagation 调用情况。

我的数据更新后,为什么渲染内容没有更新?

你可能在使用 sprite 元素,然后在渲染函数里面调用了外部数据,这样的话当外部数据更新时,你的 sprite 元素并不会自动更新,需要手动更新。手动更新参考代码:

import { Sprite } from '@motajs/render';

const mySprite = ref<Sprite>();
// 数据更新时,同时更新 sprite 元素
watch(data, () => mySprite.value?.update());

// 将 mySprite 传入 ref 参数,这样当挂载完毕后就会将 mySprite.value 设置为该元素
<sprite ref={mySprite} render={render} />;

除此之外还可能你的数据不是响应式数据,确保你的数据经过了 reactiveref 包裹。

我的 UI 很卡

可能使用了平铺式布局,建议使用 Scroll 组件或者 Page 组件来对平铺内容分割,从而提高渲染效率。可以参考对应的 API 文档

玩着玩着突然黑屏了一下,然后画面就不显示了

你应该遇到了内存泄漏问题,当一个元素被卸载后,它应该会被销毁,但是如果没有被预期销毁,那么会导致内存泄漏,最终导致爆显存,就会导致画面黑屏一下,然后内容就会不显示。样板本身已经针对这个问题进行了处理,一般情况下不会出现问题,出现这个问题时大概率是你自己的组件或 UI 有问题。可能原因有很多,例如你声明了一个列表,当组件挂载时将元素放入列表,但是当组件卸载时,你却没有将元素移除,这时候就会导致这个元素无法正确被垃圾回收,从而引起内存泄漏。

关于这个问题的最佳实践:

  • 如果你手动存储了一些元素,确保在卸载时将它们删除
  • 在删除它们的同时,调用它们的 destroy 方法,来确保可以被垃圾回收
  • 在控制台输入 Mota.require('@motajs/render').MotaOffscreenCanvas2D.list 来查看当前还有哪些画布正在使用,游玩一段时间后再次输入,检查数量是否增长,如果增长,说明发生了内存泄漏
  • 确保组件卸载时已经清空了定时器等内容
  • 如果需要每帧执行函数,请使用 onTick 接口,而非其他方法

如果你直接使用 MotaOffscreenCanvas2D 接口,请确保:

  • 在使用前调用了 activate 方法
  • 在使用后调用了 deactivate 方法
  • 如果不需要再修改画布属性,只需要绘制,请调用 freeze 方法
  • 如果之后不再使用该画布,请调用 destroy 方法

为什么我的滤镜不显示?

很遗憾截止目前2.B 发布日期IOS 依然没有支持 CanvasRenderingContext2D 上的 filter 方法,所有滤镜属性在 IOS 上将不会显示。不过,我们提供了 Shader 元素,它使用 WebGL2 接口,允许你制作自己的滤镜,如果滤镜是必要的,请考虑使用此元素,但是需要一定的图形学基础,可以在造塔群询问我或造塔辅助 AI。

不同设备的显示内容会不一样吗?

从理论上来讲,除了上面那个问题提到的滤镜,其他的所有内容的渲染结果应该完全一致,如果出现了不一致的情况,请上报样板 bug。