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

SwiftUI实现带递增序号的排序FireStore排行榜

SwiftUI 排行榜:分数排序与名次显示实现

1. 确认Leader模型结构

先保证你的Leader模型包含分数属性,示例如下:

struct Leader: Identifiable {
    let id: String
    let name: String
    let score: Int // 分数类型可根据需求换成Double
    // 其他自定义属性
}

2. 在ViewModel中完成数据排序

在LeaderboardViewModel里,把从FireStore拉取到的原始数据按分数降序排列(要升序就把>换成<):

class LeaderboardViewModel: ObservableObject {
    @Published var leaders: [Leader] = []
    
    func fetchLeaders() {
        // 这里放你已经实现的FireStore数据获取逻辑
        // 获取到数据后执行排序
        leaders = fetchedLeaders.sorted { $0.score > $1.score }
    }
}

3. 列表中显示名次

利用enumerated()遍历排序后的数组,索引从0开始,所以名次需要+1:

struct LeaderboardView: View {
    @StateObject var viewModel = LeaderboardViewModel()
    
    var body: some View {
        List(viewModel.leaders.enumerated(), id: \.element.id) { index, leader in
            HStack {
                // 显示名次
                Text("\(index + 1)")
                    .font(.headline)
                    .frame(width: 30)
                
                VStack(alignment: .leading) {
                    Text(leader.name)
                    Text("分数: \(leader.score)")
                        .font(.caption)
                        .foregroundColor(.secondary)
                }
            }
        }
        .onAppear {
            viewModel.fetchLeaders()
        }
    }
}

可选:处理并列分数的名次逻辑

如果需要支持同分数同名次(比如两个100分都显示第1名,下一个显示第3名),可以在ViewModel里加一个计算属性来处理:

// 在LeaderboardViewModel中添加
var rankedLeaders: [(rank: Int, leader: Leader)] {
    guard !leaders.isEmpty else { return [] }
    
    var rankedList: [(Int, Leader)] = []
    var currentRank = 1
    var previousScore = leaders[0].score
    
    for (index, leader) in leaders.enumerated() {
        if leader.score != previousScore {
            currentRank = index + 1
            previousScore = leader.score
        }
        rankedList.append((currentRank, leader))
    }
    
    return rankedList
}

之后在列表中遍历这个计算属性即可:

List(viewModel.rankedLeaders, id: \.leader.id) { rankItem in
    HStack {
        Text("\(rankItem.rank)")
            .font(.headline)
            .frame(width: 30)
        
        VStack(alignment: .leading) {
            Text(rankItem.leader.name)
            Text("分数: \(rankItem.leader.score)")
                .font(.caption)
                .foregroundColor(.secondary)
        }
    }
}

内容的提问来源于stack exchange,提问作者Kieron Joy-Kimber

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 17:26:04