带自定义ID的动态Picker实现问题:无法获取选中项ID
解决方案:让Picker关联自定义ID并显示名称
问题核心在于你当前仅使用了字符串数组存储名称,丢失了对应的ID关联信息。只需直接使用解码后的[UnnamedDeck]模型数组构建Picker,即可同时实现名称展示与ID获取。
1. 调整View的数据存储与异步加载逻辑
在你的View中,直接存储完整的UnnamedDeck数组,并绑定选中的模型(或ID):
struct YourDeckPickerView: View { @State private var unnamedDecks: [UnnamedDeck] = [] @State private var selectedDeck: UnnamedDeck? // 绑定整个模型,便于获取所有字段 var body: some View { Picker("选择卡组", selection: $selectedDeck) { // 用UnnamedDeck数组构建选项,指定唯一标识为ID ForEach(unnamedDecks, id: \.ID) { deck in Text(deck.name) } } // 异步加载数据 .task { if let deckList = await getUnnamedDecksList() { self.unnamedDecks = deckList.decks // 可选:设置默认选中第一个选项 self.selectedDeck = deckList.decks.first } } // 监听选中变化,获取ID .onChange(of: selectedDeck) { newSelectedDeck in if let deckID = newSelectedDeck?.ID { print("当前选中的卡组ID:\(deckID)") // 在这里处理ID的后续业务逻辑 } } } }
2. 可选:仅绑定ID字符串
如果不需要完整模型,仅需获取ID,可修改为绑定字符串类型的ID:
struct YourDeckPickerView: View { @State private var unnamedDecks: [UnnamedDeck] = [] @State private var selectedDeckID: String = "" var body: some View { Picker("选择卡组", selection: $selectedDeckID) { ForEach(unnamedDecks, id: \.ID) { deck in // 给每个选项标记对应的ID Text(deck.name).tag(deck.ID) } } .task { if let deckList = await getUnnamedDecksList() { self.unnamedDecks = deckList.decks self.selectedDeckID = deckList.decks.first?.ID ?? "" } } .onChange(of: selectedDeckID) { id in print("当前选中的卡组ID:\(id)") } } }
3. 修复数据获取函数的冗余操作
你的getUnnamedDecksList中存在不必要的Data转String再转回Data的操作,直接用原始Data解码即可:
func getUnnamedDecksList() async -> UnnamedDeckList? { let downloadTask = Task { () -> UnnamedDeckList in let url : String = "****" var components = URLComponents(string: url)! components.queryItems = [ URLQueryItem(name: "action", value: "unnamedDecks") ] components.percentEncodedQuery = components.percentEncodedQuery?.replacingOccurrences(of: "+", with: "%2B") let (data, _) = try await URLSession.shared.data(from: components.url!) // 直接使用原始Data解码,去掉冗余转换步骤 return try JSONDecoder().decode(UnnamedDeckList.self, from: data) } let result = await downloadTask.result do { return try result.get() } catch { print("数据获取失败:\(error)") return nil } }
内容的提问来源于stack exchange,提问作者Ceri Turner
相关产品推荐
相关产品推荐

