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

SwiftUI中如何在移除视图前应用其内置动画效果?

问题分析

当removable开关启用时,点击按钮会立即将视图从ForEach的数据源中移除(因为unanimatedNames会排除已加入animatedNames的项),导致SwiftUI无法对视图的背景色变化应用动画——视图在动画执行前就已经脱离了视图层级。

解决方案

我们需要让视图先完成背景色动画,再延迟将其从列表中移除。具体实现如下:

struct SelfAnimatingView: View {
    let name: String
    let animate: Bool

    var body: some View {
        Text(name)
            .padding()
            .foregroundStyle(.white)
            .background(animate ? .red : .blue)
    }
}

struct ContentView: View {
    @State private var removable = false
    @State private var names = ["Ted", "Barney", "Lily", "Robin", "Marshal"]
    @State private var animatingNames = Set<String>()
    @State private var removedNames = Set<String>()
    
    // 显示所有未被永久移除的项
    private var displayedNames: [String] {
        names.filter { !removedNames.contains($0) }
    }

    var body: some View {
        VStack {
            Toggle("Removable", isOn: $removable).padding()
            
            ForEach(displayedNames, id: \.self) { name in
                Button {
                    animatingNames.insert(name)
                    
                    // 若启用移除功能,在动画完成后再标记为永久移除
                    if removable {
                        // 匹配SwiftUI默认动画时长(约0.3秒)
                        DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) {
                            removedNames.insert(name)
                            animatingNames.remove(name)
                        }
                    }
                } label: {
                    SelfAnimatingView(name: name, animate: animatingNames.contains(name))
                }
                // 为背景色变化单独应用动画
                .animation(.default, value: animatingNames.contains(name))
            }
            
            Spacer()
        }
        // 为列表项的移除应用延迟动画
        .animation(.default.delay(1), value: displayedNames)
    }
}

效果说明

  • 当removable关闭时:点击按钮仅触发背景色从蓝色到红色的动画,视图会保留在列表中。
  • 当removable开启时:点击按钮先执行背景色动画,0.3秒后将视图标记为永久移除,触发列表项的延迟移除动画(1秒延迟与原代码保持一致)。

这样就能确保视图在被视觉移除前,完整执行其内置的背景色动画。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 19:47:48