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

SwiftUI中使用结构体作为Picker元素时如何保存切换后的值?

问题解决思路

核心问题是你当前修改的是selectedPlayer这个副本,而非playerList数组里的原始玩家实例,切换Picker后自然丢失数据。以下是具体修复步骤:

关键修改点

  • 将playerList声明为@State变量,让SwiftUI能跟踪数组内元素的变化
  • Picker绑定数组索引而非直接绑定Players实例,确保修改的是数组里的原始数据
  • 移除冗余的hours状态变量,直接绑定到选中玩家的hourString

修改后的完整代码

import SwiftUI

struct Players: Hashable {
    var playerNumber: String
    var killString: String
    var kills: Double
    var hourString: String
    var hours: Double
}

struct ContentView: View {
    
    // 改为@State变量,允许修改数组内的元素
    @State private var playerList: [Players] = [
        Players(playerNumber: "Player 1", killString: "", kills: 0, hourString: "", hours: 0),
        Players(playerNumber: "Player 2", killString: "", kills: 0, hourString: "", hours: 0),
        Players(playerNumber: "Player 3", killString: "", kills: 0, hourString: "", hours: 0),
        Players(playerNumber: "Player 4", killString: "", kills: 0, hourString: "", hours: 0),
        Players(playerNumber: "Player 5", killString: "", kills: 0, hourString: "", hours: 0),
    ]
    
    // 绑定数组索引,而非直接绑定Players实例
    @State private var selectedPlayerIndex = 0
    
    var body: some View {
        NavigationView {
            VStack(spacing: 30){
                Group{
                    Text(playerList[selectedPlayerIndex].playerNumber)
                        .font(.system(size: 50))
                }.frame(width:350, height: 100)
                    .background(Color("AppSwag")).cornerRadius(30)
                    .foregroundColor(.white)
                Text("Select a Player")
                    .padding(10)
                Picker("Select Player", selection: $selectedPlayerIndex){
                    ForEach(playerList.indices, id: \.self) { index in
                        Text(playerList[index].playerNumber)
                    }
                }.pickerStyle(.segmented)
                
                HStack{
                    Text("Enter Players Hours:")
                    // 直接绑定到选中玩家的hourString,无需中间变量
                    TextField("", text: $playerList[selectedPlayerIndex].hourString)
                        .frame(width: 150, height: 50)
                        .background(Color.gray.opacity(0.5))
                        .cornerRadius(10)
                }
                
                HStack{
                    Text("Enter Players Kills:")
                    TextField("", text: $playerList[selectedPlayerIndex].killString)
                        .frame(width: 150, height: 50)
                        .background(Color.gray.opacity(0.5))
                        .cornerRadius(10)
                }
                Text("\(playerList[selectedPlayerIndex].playerNumber)'s values: \(playerList[selectedPlayerIndex].hourString) ")
            }// Vstack
            .navigationTitle("CSGO Calculator")
            .padding()
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

额外说明

  • 因为结构体是值类型,直接修改selectedPlayer只会修改副本,而通过索引操作playerList里的元素,才会真正修改数据源
  • 移除onSubmit是因为直接绑定TextField到数据源,输入时会实时更新,无需手动提交(如果需要提交后再更新,可以保留onSubmit,但要更新数组对应元素)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 10:31:05