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

SwiftUI中如何在Observed属性变更时触发视图动画?

SwiftUI:通过ObservableObject的@Published属性触发图片动画

我原本通过点击图片修改本地@State属性可以实现图片缩放动画,现在需要实现的是:当ObservableObject内部的@Published属性动态变更时,每次都触发图片的缩放动画。

使用本地@State属性包装器(运行正常)

struct ContentView: View {
    @State private var scaleValue = 1.0
    @State private var isAnimating: Bool = true
        
    var body: some View {
        
        Image(systemName: "circle.fill")
            .scaleEffect(scaleValue)
            .font(.title)
            .foregroundColor(.green)
            .animation(.easeOut(duration: 0.3), value: isAnimating)
            .onTapGesture {
                self.isAnimating.toggle()
                self.scaleValue = 1.5
                DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 0.3){
                    self.scaleValue = 1.0
                }
            }
    }
}

使用被观察的@Published属性包装器(无法正常运行,不确定动画逻辑位置)

struct ContentView: View {
    @State private var scaleValue = 1.0       
    @StateObject private var contentVM = ContentViewModel()
    
    var body: some View {
        
        Image(systemName: "circle.fill")
            .scaleEffect(scaleValue)
            .font(.title)
            .foregroundColor(.green)
            .animation(.easeOut(duration: 0.3), value: contentVM.isAnimating)
           // 不确定该在哪里添加触发动画的逻辑

    }
}

可行解决方案

感谢@Fogmeister和@burnsi提供思路

class ContentViewModel: ObservableObject{
     @Published var isAnimatingImage = false 
}

struct ContentView2: View {
    @StateObject private var contentVM = ContentViewModel()
    @State private var scaleValue = 1.0
    
    var body: some View {
        Image(systemName: "circle.fill")
            .scaleEffect(scaleValue)
            .font(.title)
            .foregroundColor(.green)
            .animation(.easeOut(duration: 0.3), value: scaleValue)
            .onChange(of: contentVM.isAnimatingImage) { _ in
                animateImage()
            }
    }

    func animateImage(){
        scaleValue = 1.5
        DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 0.3){
            self.scaleValue = 1.0
        }
    }
}

注:原解决方案中在body内部声明@State的写法不符合SwiftUI规范,已调整至结构体属性声明位置


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 00:01:19