uni-app 使用 setup 做动画效果时,安卓正常,iOS只能做一次。
uni-app 使用 setup 做动画效果时,安卓正常,iOS只能做一次。
开发环境 | 版本号 | 项目创建方式 |
---|---|---|
Mac | 13.5 | HBuilderX |
产品分类:uniapp/App
PC开发环境操作系统:Mac
HBuilderX类型:正式
HBuilderX版本号:4.24
手机系统:iOS
手机系统版本号:iOS 17
手机厂商:模拟器
手机机型:SE
页面类型:vue
vue版本:vue3
打包方式:云端
示例代码:
```html
<template>
<view style="flex: 1;" >
<view
class="base-style transition-transform"
:class="{ 'translate': isTransformTranslate }"
@click="changeTransformTranslate"
></view>
</view>
</template>
<script setup>
const isTransformTranslate = ref(false);
const changeTransformTranslate = () => {
isTransformTranslate.value = !isTransformTranslate.value;
};
</script>
<style>
.base-style {
width: 200px;
height: 200px;
background-color: brown;
}
.transition-transform {
transition-property: transform;
transition-duration: 1s;
}
.translate {
transform: translate(0, 100%);
}
</style>
```
```
操作步骤:
- iOS在模拟器运行,点击view做动画效果
预期结果:
- iOS在模拟器运行,view可以来回点击
实际结果:
- iOS在模拟器运行,view只能点击一次
bug描述:
参考 https://doc.dcloud.net.cn/uni-app-x/css/transition.html 中的教程,把其中的`点击修改TransformTranslate`代码由选项式改为组合式,并把动画改为css效果。安卓运行正常,iOS在模拟器上只能点击一次,做一次动画,再点击无效。代码如下:
在使用uni-app开发跨平台应用时,如果发现在iOS上动画效果只能执行一次,而在安卓上表现正常,这通常与事件绑定、状态更新或动画库的兼容性问题有关。以下是一个使用Vue 3的Composition API(即setup
语法)实现的简单动画效果示例,并附带了一些可能的解决方案,以确保动画在iOS上也能正常多次执行。
示例代码
首先,确保你的uni-app项目已经配置好支持Vue 3和Composition API。
<template>
<view class="container">
<button @click="startAnimation">Start Animation</button>
<view class="box" :style="boxStyle"></view>
</view>
</template>
<script setup>
import { ref, onMounted, onUnmounted } from 'vue';
const boxStyle = ref({
transform: 'translateX(0)',
transition: 'transform 0.5s ease'
});
let animationFrameId = null;
const startAnimation = () => {
if (animationFrameId) {
cancelAnimationFrame(animationFrameId); // 防止重复动画
}
let position = 0;
const animate = () => {
position = (position + 10) % 300; // 模拟移动范围0-300px
boxStyle.value.transform = `translateX(${position}px)`;
animationFrameId = requestAnimationFrame(animate);
};
// 使用requestAnimationFrame来确保动画平滑
animationFrameId = requestAnimationFrame(animate);
};
onUnmounted(() => {
if (animationFrameId) {
cancelAnimationFrame(animationFrameId);
}
});
</script>
<style scoped>
.container {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 100vh;
}
.box {
width: 50px;
height: 50px;
background-color: red;
}
button {
margin-bottom: 20px;
}
</style>
解决思路
-
使用
requestAnimationFrame
:确保动画在iOS上也能平滑运行,避免使用简单的setInterval
或setTimeout
,因为requestAnimationFrame
与浏览器的渲染周期更同步。 -
清理动画帧:在组件卸载或重新开始动画前,确保使用
cancelAnimationFrame
来清理之前的动画帧,避免潜在的内存泄漏或动画冲突。 -
状态管理:确保动画状态(如位置、速度等)被正确管理,避免由于状态更新不当导致的动画中断。
-
测试与调试:使用真机测试,特别是iOS设备,因为模拟器可能无法完全模拟真机的行为。使用开发者工具查看控制台输出,检查是否有错误或警告。
通过上述方法,你应该能够解决iOS上动画只能执行一次的问题。如果问题依旧存在,可能需要检查uni-app或Vue 3的相关issue,看是否有已知的兼容性问题。