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

SwiftUI如何为List Section行实现显示/隐藏时的自定义滑入滑出动画

SwiftUI List Section 行自定义滑入滑出动画实现

要实现Section行显示时从上到下滑入、隐藏时从下到上滑出的自定义动画,你需要给每个行添加基于状态的位置和透明度动画,同时利用索引实现错落的动画时序,让效果更自然。以下是修改后的完整代码:

struct AnimateListRows: View {
    
    let rowValues = Array(0...10)
    @State private var showSection = false
    
    var body: some View {
        List {
            ForEach(rowValues, id: \.self) {
                ListRow(rowValue: $0)
            }
            
            Section {
                if showSection {
                    // 带索引遍历,实现行动画的错落效果
                    ForEach(Array(rowValues.enumerated()), id: \.element) { index, value in
                        ListRow(rowValue: value)
                            .animation(
                                Animation.easeInOut(duration: 0.3)
                                    .delay(Double(index) * 0.05), // 每行延迟递增,营造连贯滑入效果
                                value: showSection
                            )
                            .offset(y: showSection ? 0 : 20) // 隐藏时向下偏移
                            .opacity(showSection ? 1 : 0)
                    }
                } else {
                    // 隐藏时从最后一行开始依次滑出
                    ForEach(Array(rowValues.enumerated()), id: \.element) { index, value in
                        ListRow(rowValue: value)
                            .animation(
                                Animation.easeInOut(duration: 0.3)
                                    .delay(Double(rowValues.count - 1 - index) * 0.05),
                                value: showSection
                            )
                            .offset(y: showSection ? 0 : 20)
                            .opacity(showSection ? 1 : 0)
                    }
                }
            } header: {
                HStack {
                    Text("Section")
                    Spacer()
                    Image(systemName: showSection ? "chevron.down" : "chevron.right") // 切换图标更直观
                        .foregroundColor(.blue)
                        .onTapGesture {
                            withAnimation {
                                showSection.toggle()
                            }
                        }
                }
            }
            
            ForEach(rowValues, id: \.self) {
                ListRow(rowValue: $0)
            }
        }
    }
}

struct ListRow: View {
    let rowValue: Int
    var body: some View {
        Text("Row \(rowValue)")
            .padding(.vertical, 8)
    }
}

struct AnimateListRows_Previews: PreviewProvider {
    static var previews: some View {
        AnimateListRows()
    }
}

关键实现细节:

  • 错落动画时序:通过enumerated()获取行索引,给每行添加递增/反向递增的延迟,避免所有行同时触发动画,提升视觉流畅度。
  • 自定义动画参数:用offset(y:)控制行的滑动方向,opacity控制淡入淡出,搭配easeInOut曲线让过渡更平滑。
  • 状态绑定动画:将动画绑定到showSection状态,确保状态切换时自动触发行的动画效果。

如果你的ListRow是复杂自定义视图,确保使用稳定的id或让视图遵循Identifiable协议,避免动画过程中出现视图复用异常。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 02:20:40