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

SwiftUI列表动画切换真实数据后异常的解决方法

SwiftUI排名列表动画在动态数据下异常,移除removeAll后恢复正常

问题概述

为游戏总分列表实现了动画效果:保存用户历史结果,下次打开视图时,用户的结果条目会从旧排名位置平滑移动到新位置。测试阶段用硬编码假数据时动画表现正常,但切换为服务器返回的动态数据后,动画出现严重异常。

排查后确认问题核心在ViewModel的setResultData方法中:

  • 使用动态生成的oldResults时动画异常
  • 硬编码假数据时动画正常
  • 移除removeAll(where: {$0.uuid == previousResult.uuid})语句后,动画恢复正常

代码示例

1. Model定义

struct ScoreResult: Identifiable {
    let id = UUID()
    let uuid: String
    let userName: String
    let score: Int
    // 其他业务字段
}

2. ViewModel核心代码

class ScoreViewModel: ObservableObject {
    @Published var results: [ScoreResult] = []
    private var previousResult: ScoreResult?
    private let currentUserUUID = "user_123" // 示例用户UUID

    func setResultData(newResults: [ScoreResult]) {
        // 动态生成旧数据集合(触发异常的场景)
        var oldResults = self.results
        // 保存当前用户的历史结果
        previousResult = oldResults.first(where: { $0.uuid == currentUserUUID })
        
        // 问题代码:移除该行后动画恢复正常
        // oldResults.removeAll(where: {$0.uuid == previousResult?.uuid})
        
        // 执行动画更新数据
        withAnimation {
            self.results = newResults
        }
    }

    // 从服务器获取动态数据
    func fetchResultsFromServer() async {
        let fetchedResults = await APIManager.getScoreResults()
        DispatchQueue.main.async {
            self.setResultData(newResults: fetchedResults)
        }
    }
}

// 模拟API请求工具类
struct APIManager {
    static func getScoreResults() async -> [ScoreResult] {
        // 模拟服务器返回动态数据
        return [
            ScoreResult(uuid: "user_456", userName: "PlayerA", score: 980),
            ScoreResult(uuid: "user_123", userName: "Me", score: 920),
            ScoreResult(uuid: "user_789", userName: "PlayerB", score: 850)
        ]
    }
}

3. SwiftUI视图代码

struct ScoreListView: View {
    @StateObject private var viewModel = ScoreViewModel()

    var body: some View {
        List(viewModel.results) { result in
            HStack {
                Text(result.userName)
                Spacer()
                Text("\(result.score)")
            }
        }
        .onAppear {
            Task {
                await viewModel.fetchResultsFromServer()
            }
        }
    }
}

动画效果对比

  • 正常动画:用户条目从旧排名位置平滑过渡到新位置,其他条目同步自然调整位置,无跳动、闪烁或布局混乱
  • 异常动画:条目出现突兀跳转、闪烁,部分条目位置瞬间变化,完全失去平滑过渡效果

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 06:12:11