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

如何在SwiftUI中遍历字典生成带地区分区的List列表

解决方案

错误原因

SwiftUI 的ForEach仅支持遍历符合RandomAccessCollection协议的集合类型,直接传入Dictionary类型会触发类型不匹配报错。同时字典本身是无序集合,不做排序直接遍历会导致分区顺序每次页面刷新都随机变化,影响使用体验。

实现步骤

1. 基础协议适配

首先确保你的Country模型遵守Identifiable协议(若不想遵守也可后续手动指定遍历id):

struct Country: Identifiable, Hashable {
    let id = UUID()
    // 原有属性示例
    let name: String
    let countryCode: String
}

2. 完整代码实现

推荐先对地区名排序后再遍历,保证分区顺序稳定:

// iOS 16及以上版本使用NavigationStack(原NavigationView已废弃)
NavigationStack {
    List {
        // 提取所有地区key排序后遍历,用key本身作为唯一id
        ForEach(countriesGroupedByRegion.keys.sorted(), id: \.self) { region in
            // 每个地区对应一个分区
            Section(header: Text(region)) {
                // 遍历当前地区下的所有国家
                ForEach(countriesGroupedByRegion[region] ?? []) { country in
                    // 自定义国家单元格布局,此处仅做示例
                    Text(country.name)
                }
            }
        }
    }
    .navigationTitle("按地区划分国家")
}

可选优化方案

你也可以提前将字典转换为排序后的键值对数组,避免每次页面渲染都重复执行排序逻辑,性能更优:

// 可放在ViewModel中提前处理,数据变更时再更新
let sortedRegionList: [(region: String, countries: [Country])] = countriesGroupedByRegion
    .map { (region: $0.key, countries: $0.value) }
    .sorted { $0.region < $1.region }

// 遍历逻辑简化为
ForEach(sortedRegionList, id: \.region) { item in
    Section(header: Text(item.region)) {
        ForEach(item.countries) { country in
            Text(country.name)
        }
    }
}

特殊情况适配

如果你的Country模型没有遵守Identifiable协议,只需要修改国家遍历的代码,手动指定id即可:

ForEach(countriesGroupedByRegion[region] ?? [], id: \.self) { country in
    Text(country.name)
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.23 15:45:02