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

如何在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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 12:30:55