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

SwiftUI如何不使用range和count实现车型级联选择器?

实现SwiftUI品牌-车型级联选择器

你需要实现一个级联选择器,第二个车型选择器的选项随第一个品牌选择器的结果动态加载,数据来自Bundle中的JSON文件。目前品牌选择器可正常运行,但车型选择器的实现存在类型不匹配(vehicleMake和vehicleModel为String类型,原代码误用Int索引)的问题,希望不通过range和count实现功能。


现有代码问题

品牌选择器可正常运行:

Picker("Make", selection: $vehicle.vehicleMake) {
    ForEach(Manufacturer.allManufacturers) { index in
        Text(index.make)
    }
}

原尝试的车型选择器代码错误在于:用String类型的vehicleModel作为数组索引,且ForEach使用方式不符合要求。


解决方案

可以直接基于String类型的vehicleMake和vehicleModel实现级联,无需转换为Int索引,具体实现如下:

完整PickerView代码

import SwiftUI

struct PickerView: View {
    @ObservedObject var vehicle: Vehicle
    
    // 动态获取当前选中品牌对应的车型列表
    private var currentModels: [String] {
        guard let selectedBrand = Manufacturer.allManufacturers.first(where: { $0.make == vehicle.vehicleMake }) else {
            return []
        }
        return selectedBrand.models
    }
    
    var body: some View {
        Picker("品牌", selection: $vehicle.vehicleMake) {
            ForEach(Manufacturer.allManufacturers) { brand in
                Text(brand.make)
                    .tag(brand.make) // 显式绑定String类型的品牌名称
            }
        }
        
        // 仅当有选中品牌时显示车型选择器
        if !currentModels.isEmpty {
            Picker("车型", selection: $vehicle.vehicleModel) {
                ForEach(currentModels, id: \.self) { model in
                    Text(model)
                        .tag(model) // 显式绑定String类型的车型名称
                }
            }
        }
    }
}

关键说明

  • 显式设置tag:遍历Manufacturer时显式指定tag(brand.make),确保绑定值与vehicleMake的String类型匹配;车型选择器同理绑定String类型的车型名称。
  • 动态过滤车型:通过first(where:)匹配当前选中的品牌,直接获取对应车型数组,避免了不安全的Int索引操作。
  • 空状态处理:未选中品牌时隐藏车型选择器,也可根据需求添加提示文本。

保留原有相关代码

Core Data的Vehicle扩展

import Foundation

extension Vehicle {
    var vehicleMake: String {
        get { make ?? "" }
        set { make = newValue }
    }

    var vehicleModel: String {
        get { model ?? "" }
        set { model = newValue }
    }
}

Manufacturer结构体

import SwiftUI

struct Manufacturer: Decodable, Identifiable {
    var id: String { make }
    var make: String
    var models: [String]

    static let allManufacturers = Bundle.main.decode("Manufacturers.json", as: [Manufacturer].self)
    static let example = allManufacturers[0]
}

JSON数据文件

[
  {
    "make": "Toyota",
    "models": ["Corolla", "Camry", "RAV4"]
  },
  {
    "make": "Honda",
    "models": ["Civic", "Accord", "CR-V"]
  },
  {
    "make": "Ford",
    "models": ["Mustang", "F-150", "Explorer"]
  }
]

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 21:36:25