SwiftUI多输入网格数据独立存储:如何创建嵌套二维数组结构
解决方案
核心问题
你当前所有网格共用同一个names二维数组作为绑定数据源,因此任意一个输入框的修改都会同步修改全局数组,导致所有网格显示内容一致。你需要为每一个选中的导弹分别创建独立的二维数组存储对应网格的输入数据。
具体修改步骤
1. 替换全局存储结构
将AttackParametersView中原来的单二维数组状态,替换为以导弹名称为键、对应网格二维数组为值的字典:
// 替换原来的 @State var names = [[String]]() @State var missileGridData: [String: [[String]]] = [:]
2. 修改导弹选中时的初始化逻辑
在导弹选择的回调中,为每个新选中的导弹单独初始化对应的空二维数组,取消选中时移除对应存储:
ForEach(missiles, id: \.self) { missile in MultipleSelectionRow(title: missile, isSelected: self.missileSelections.contains(missile)) { if self.missileSelections.contains(missile) { self.missileSelections.removeAll(where: { $0 == missile }) // 移除取消选中的导弹对应的数据 self.missileGridData.removeValue(forKey: missile) } else { self.missileSelections.append(missile) // 为新选中的导弹初始化独立的二维数组 let emptyGrid = [[String]](repeating: [String](repeating: "", count: targetSelections.count), count: launchPointsSelections.count) self.missileGridData[missile] = emptyGrid } } }
3. 给每个MissileView绑定独立数据源
遍历生成导弹网格时,传入对应导弹专属的二维数组绑定:
ForEach(missileSelections, id:\.self) { missile in if showGreeting{ Text(missile).padding() // 绑定当前导弹对应的独立二维数组 MissileView( launchPointCount: $launchPointsSelections, targetCount: $targetSelections, names: Binding( get: { self.missileGridData[missile] ?? [] }, set: { self.missileGridData[missile] = $0 } ) ).padding(.horizontal, 20) } }
4. 调整后续数据读取逻辑
原来的打印逻辑需要修改为遍历每个导弹对应的网格数据:
Button(action: { self.showingOperatingConditions.toggle() // 遍历所有导弹的独立网格数据 for missile in missileSelections { guard let grid = missileGridData[missile] else { continue } print("=== 导弹:\(missile) 的网格数据 ===") for i in 0 ..< grid.count { for j in 0 ..< grid[i].count { print(launchPointsSelections[i]) print(targetSelections[j]) print(grid[i][j]) } } } }) { Text("Next") }
可选优化
如果需要更稳定的类型约束,也可以创建一个结构体存储导弹+网格的关联数据:
struct MissileGrid: Identifiable { let id = UUID() let missileName: String var gridData: [[String]] }
然后将存储结构改为@State var missileGrids: [MissileGrid] = [],逻辑和上述字典方案一致。
内容的提问来源于stack exchange,提问作者Luke Tomlinson
相关产品推荐
相关产品推荐

