如何在UIPickerView中展示选中城市对应的JSON区县数据?
城市与区县Picker联动实现方案
问题描述
拥有2个TextView和2个UIPickerView,需求是用户选择城市后,第二个UIPickerView自动显示该城市对应的区县列表。已完成本地JSON数据加载及Codable模型定义,第一个PickerView可正常显示城市,但第二个PickerView的行数计算与标题获取逻辑存在问题。
解决方案
1. 添加选中城市索引变量
在ViewController中新增变量,记录当前选中的城市索引,作为城市与区县数据的关联核心:
var selectedCityIndex = 0 // 默认选中第一个城市 var selectedCity: cityOfModel?
2. 修复第二个PickerView的行数计算逻辑
修改numberOfRowsInComponent方法,第二个Picker的行数对应当前选中城市的区县数组长度:
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int { switch pickerView.tag { case 1: return selectedCity?.data.count ?? 0 case 2: // 安全获取选中城市的区县数量,避免空值或越界 guard let selectedCity = selectedCity, selectedCityIndex < selectedCity.data.count else { return 0 } return selectedCity.data[selectedCityIndex].ilceler.count default: return 0 } }
3. 修复区县标题获取逻辑
修改titleForRow方法,从选中城市的区县数组中读取对应行的名称:
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? { switch pickerView.tag { case 1: return selectedCity?.data[row].ilAdi ?? "无数据" case 2: guard let selectedCity = selectedCity, selectedCityIndex < selectedCity.data.count, row < selectedCity.data[selectedCityIndex].ilceler.count else { return "无数据" } return selectedCity.data[selectedCityIndex].ilceler[row].ilceAdi default: return "错误" } }
4. 实现Picker选中事件联动
添加didSelectRow代理方法,当第一个Picker选中城市时,更新索引并刷新第二个Picker:
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) { if pickerView.tag == 1 { selectedCityIndex = row // 刷新第二个PickerView加载对应区县 if let districtPicker = view.viewWithTag(2) as? UIPickerView { districtPicker.reloadAllComponents() } // 更新城市TextView显示 if let cityTextView = view.viewWithTag(101) as? UITextView { cityTextView.text = selectedCity?.data[row].ilAdi } } else if pickerView.tag == 2 { // 更新区县TextView显示 guard let selectedCity = selectedCity, selectedCityIndex < selectedCity.data.count, row < selectedCity.data[selectedCityIndex].ilceler.count else { return } if let districtTextView = view.viewWithTag(102) as? UITextView { districtTextView.text = selectedCity.data[selectedCityIndex].ilceler[row].ilceAdi } } }
5. 初始化数据后的处理
在数据加载完成后,刷新两个PickerView确保初始显示正常:
func ilce(){ guard let path = Bundle.main.path(forResource: "yusif", ofType: "json") else {return} let url = URL(fileURLWithPath: path) do{ let jsonData = try Data(contentsOf: url) selectedCity = try JSONDecoder().decode(cityOfModel.self, from: jsonData) // 刷新城市Picker if let cityPicker = view.viewWithTag(1) as? UIPickerView { cityPicker.reloadAllComponents() } // 初始化区县Picker显示 if let districtPicker = view.viewWithTag(2) as? UIPickerView { districtPicker.reloadAllComponents() } } catch{ print("数据解析错误:\(error.localizedDescription)") } }
关键说明
- 所有数据访问都添加了可选绑定和边界判断,避免数组越界或空值崩溃
selectedCityIndex是联动逻辑的核心,用于关联当前选中城市和对应区县数据- 选中城市后必须调用
reloadAllComponents()才能触发第二个PickerView更新显示
内容的提问来源于stack exchange,提问作者yusuf kutlay
相关产品推荐
相关产品推荐

