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
相关产品推荐
相关产品推荐

