You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SwiftUI弹出动画在真机上导致文字抖动问题求助

SwiftUI文字动画真机抖动问题解决方案

问题描述

我在SwiftUI中实现了一个包含文字与图片的弹出动画,模拟器预览显示正常,但真机运行时文字会出现明显抖动,图片动画却表现正常。尝试过移除阴影、调整动画幅度等操作,问题仍未解决。

问题演示:
图片动画正常,但文字抖动严重

相关代码

struct SplashScreenContent: View {

    @State private var blurRadius: CGFloat = 10
    @State private var movingShadowX: CGFloat = 4
    @State private var movingShadowY: CGFloat = 4
    @State private var imageSize: CGFloat = 50
    @State private var fontSize: CGFloat = 55
    @State private var bottomInset: CGFloat = -5
    @State private var trailingInset: CGFloat = -3

    var body: some View {
        VStack {
            Button("Animate", action: buttonPress)
            Spacer()
            VStack(spacing: 45) {
                Image(systemName: "house")
                    .resizable()
                    .foregroundColor(.white)
                    .scaledToFill()
                    .frame(width: imageSize, height: imageSize)
                    .shadow(color: .black, radius: 1.5)
                    .shadow(color: .yellow, radius: 5)
                    .shadow(color: .black, radius: 3, x: movingShadowX, y: movingShadowY)
                Text("I'm so\nShakey")
                    .font(.custom("NewYork-regular", size: fontSize))
                    .fontWeight(.semibold)
                    .foregroundColor(Color.white)
                    .multilineTextAlignment(.center)
                    .padding(.bottom, 70.0)
                    .shadow(color: .black, radius: 1.5)
                    .shadow(color: .yellow, radius: 5)
                    .shadow(color: .black, radius: 3, x: movingShadowX, y: movingShadowY)
            }
            .padding(.init(top: 0, leading: 0, bottom: bottomInset, trailing: trailingInset))
            .blur(radius: blurRadius)
            .onAppear(perform: animate)
            Spacer()
        }
    }
}

extension SplashScreenContent {

    func buttonPress() {
        blurRadius = 10
        movingShadowX = 4
        movingShadowY = 4
        imageSize = 50
        fontSize = 55
        bottomInset = -5
        trailingInset = -3
        animate()
    }

    func animate() {
        withAnimation(.easeIn(duration: 0.4).delay(0.8)) {
            blurRadius = 0
            withAnimation(.easeIn(duration: 4).delay(0.3)) {
                movingShadowX = 6
                movingShadowY = 9.5
                imageSize = 53
                fontSize = 58
                bottomInset = 13
                trailingInset = 3
                withAnimation(.easeIn(duration: 0.5).delay(4.3)) {
                    blurRadius = 20
                }
            }
        }

    }
}

解决办法

1. 替换文字缩放方式

直接动画fontSize会导致真机上自定义字体的浮点精度渲染偏差,改用scaleEffect基于矢量缩放文本:

Text("I'm so\nShakey")
    .font(.custom("NewYork-regular", size: 55)) // 固定基础字号
    .scaleEffect(fontSize / 55) // 用比例缩放代替直接改字号
    .fontWeight(.semibold)
    .foregroundColor(Color.white)
    .multilineTextAlignment(.center)
    .padding(.bottom, 70.0)
    .shadow(color: .black, radius: 1.5)
    .shadow(color: .yellow, radius: 5)
    .shadow(color: .black, radius: 3, x: movingShadowX, y: movingShadowY)

2. 拆分嵌套动画

多层嵌套的withAnimation可能导致UI更新不同步,拆分成顺序执行的独立动画块:

func animate() {
    // 第一步:移除模糊
    withAnimation(.easeIn(duration: 0.4).delay(0.8)) {
        blurRadius = 0
    }
    // 第二步:执行缩放和位移动画(等待第一步结束后启动)
    withAnimation(.easeIn(duration: 4).delay(1.2)) {
        movingShadowX = 6
        movingShadowY = 9.5
        imageSize = 53
        fontSize = 58
        bottomInset = 13
        trailingInset = 3
    }
    // 第三步:添加模糊(等待第二步结束后启动)
    withAnimation(.easeIn(duration: 0.5).delay(5.2)) {
        blurRadius = 20
    }
}

3. 合并文字渲染层

多层阴影叠加会增加真机渲染负担,用compositingGroup()将文字和阴影打包成单个渲染层:

Text("I'm so\nShakey")
    // 原有属性...
    .shadow(color: .black, radius: 1.5)
    .shadow(color: .yellow, radius: 5)
    .shadow(color: .black, radius: 3, x: movingShadowX, y: movingShadowY)
    .compositingGroup() // 合并渲染层

4. 优化布局偏移精度

避免用浮点值控制padding偏移,改用offset或使用整数偏移值:

// 替换原有padding
.offset(x: trailingInset, y: bottomInset)

内容的提问来源于stack exchange,提问作者CodingLamb

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 09:40:29