Swift/SwiftUI中如何动态选择字典数据实现联动选择器?
最优实现方案
1. 定义强类型数据模型(推荐)
先把API返回的字典数组转换成强类型结构体,避免字典操作的不安全:
struct RegionData: Codable { let region: String let cities: [String] }
2. 调整ContentView的状态与逻辑
保留完整的地区-城市关联数据,通过选中的地区动态过滤对应城市,同时控制第二个选择器的启用状态:
struct ContentView : View { // 从UserDefaults读取完整的地区数据数组 let regionList: [RegionData] = { guard let data = UserDefaults.standard.data(forKey: "regions"), let regions = try? JSONDecoder().decode([RegionData].self, from: data) else { return [] } return regions }() @State private var selectedRegion: String = "" @State private var selectedCity: String = "" // 实时根据选中地区过滤对应城市 private var currentCities: [String] { regionList.first { $0.region == selectedRegion }?.cities ?? [] } var body: some View { VStack(spacing: 20) { // 地区选择器 Picker("选择地区", selection: $selectedRegion) { Text("请选择地区").tag("") ForEach(regionList.map(\.region), id: \.self) { region in Text(region) } } .pickerStyle(.menu) // 城市选择器:未选地区时禁用 Picker("选择城市", selection: $selectedCity) { Text("请先选择地区").tag("") ForEach(currentCities, id: \.self) { city in Text(city) } } .pickerStyle(.menu) .disabled(selectedRegion.isEmpty) } .padding() } }
核心逻辑说明
- 保留完整关联数据:直接存储
[RegionData]数组,避免后续重新匹配地区与城市的额外操作。 - 动态过滤城市:通过计算属性
currentCities实时筛选对应城市,无需额外监听事件。 - 控制交互状态:用
disabled(selectedRegion.isEmpty)让城市选择器在未选地区时处于禁用状态,优化用户体验。 - 默认提示选项:给选择器添加默认提示项,避免初始状态下自动选中第一个选项的突兀感。
兼容方案:若只能存储地区数组
如果无法修改存储结构,可提前构建地区到城市的映射字典:
private let regionCityMap: [String: [String]] = { let rawData: [RegionData] = // 从API或原始数据源获取 return Dictionary(uniqueKeysWithValues: rawData.map { ($0.region, $0.cities) }) }() // 过滤城市改为: private var currentCities: [String] { regionCityMap[selectedRegion] ?? [] }
内容的提问来源于stack exchange,提问作者unhep
相关产品推荐
相关产品推荐

