So, I have dynamically created grids of rows and cols that are text inputs, similar to Soduko. The only issue right now is is that all of the grids hold the same value no matter which grid I fill in. 
This is the view where I am calling MissileView to create the grids based on the number of selections of missiles.
struct AttackParametersView: View {
@State var showingOperatingConditions = false
@State var launchPointsSelections: [String] = []
@State var targetSelections: [String] = []
@State var missileSelections: [String] = []
@State var names = [[String]]()
@State public var battery = "South Korea"
@State private var launchPoints = [String]()
@State private var missiles = [String]()
@State private var targets = [String]()
//let launchPoints
@State private var showGreeting = false
var body: some View {
ScrollView {
VStack(alignment: .center) {
Text("ATTACK PARAMETERS").fontWeight(.bold)
.foregroundColor(Color(hue: 0.651, saturation: 1.0, brightness: 0.465))
.multilineTextAlignment(.center).padding(.vertical).frame(maxWidth: .infinity)
VStack {
Text("1. selected battery: " + battery.uppercased())
.multilineTextAlignment(.leading)
.frame(maxWidth: .infinity)
.font(.footnote).opacity(showGreeting ? 0 : 1)
.padding(.vertical).frame(maxWidth: .infinity)
Button("load stored attack parameter set"){
}.opacity(showGreeting ? 0 : 1)
}
Spacer()
HStack(alignment: .top) {
VStack(alignment: .leading) {
Text("2. targets").font(.footnote).opacity(showGreeting ? 0 : 1)
List {
ForEach(targets, id: \.self) { target in
MultipleSelectionRow(title: target, isSelected: self.targetSelections.contains(target)) {
if self.targetSelections.contains(target) {
self.targetSelections.removeAll(where: { $0 == target })
}
else {
self.targetSelections.append(target)
}
}
}
}.frame(maxWidth: .infinity).frame(height: (showGreeting ? 0 : 250)).font(.footnote)
}
VStack(alignment: .leading) {
Text("3. launch points").font(.footnote).opacity(showGreeting ? 0 : 1)
List {
ForEach(launchPoints, id: \.self) { launchPoint in
MultipleSelectionRow(title: launchPoint, isSelected: self.launchPointsSelections.contains(launchPoint)) {
if self.launchPointsSelections.contains(launchPoint) {
self.launchPointsSelections.removeAll(where: { $0 == launchPoint })
}
else {
self.launchPointsSelections.append(launchPoint)
}
}
}
}.frame(maxWidth: .infinity).frame(height: (showGreeting ? 0 : 250)).font(.footnote)
}
VStack(alignment: .leading) {
Text("4. missiles").font(.footnote).opacity(showGreeting ? 0 : 1)
List {
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 })
}
else {
self.missileSelections.append(missile)
}
names = [[String]](repeating: [String](repeating: "",
count: targetSelections.count),
count: launchPointsSelections.count)
}
}
}.frame(maxWidth: .infinity).font(.footnote).frame(height: (showGreeting ? 0 : 250))
}
Spacer()
}.padding().frame(maxWidth: .infinity)
Toggle("Save and Show Grids", isOn: $showGreeting).padding()
ForEach(missileSelections, id:\.self) { missile in
if showGreeting{
Text(missile).padding()
MissileView(launchPointCount: $launchPointsSelections, targetCount: $targetSelections, names: $names).padding(.horizontal, 20)
}
}
}
Button(action: {
self.showingOperatingConditions.toggle()
for i in 0 ..< names.count {
for j in 0 ..< names[i].count {
print(launchPointsSelections[i])
print(targetSelections[j])
print(names[i][j])
}
}
}) {
Text("Next")
}.sheet(isPresented: $showingOperatingConditions) {
OperatingConditionsView()
}.padding(.all, 30)
}.padding().onAppear() {
loadAttackParameters(country: battery.replacingOccurrences(of: " ", with: "") ,completionHandler: { (data: [Dictionary<String, Any>]) in
for row in data {
targets = row["targets"] as! [String]
launchPoints = row["launchPoints"] as! [String]
missiles = row["missiles"] as! [String]
}
})
}
}
This is the missile view or the grid view. I am using an array called names for the grid that is a 2d array for the rows x cols grid. So I think I need an array of names, but I am not entirely sure the best way of doing this. So how can I create an array of grids or array of 2d arrays so that I can then have separate data for each grid?
struct MissileView: View {
@Binding var launchPointCount: [String]
@Binding var targetCount: [String]
@Binding var names: [[String]]
var body: some View {
VStack(alignment: .trailing){
HStack(alignment: .top) {
ForEach(targetCount, id: \.self) { item in
Text(item)
.font(.custom("Gill Sans", size: 10))
.rotationEffect(.degrees(45))
.padding(.horizontal, 10)
}
}.frame(maxWidth: .infinity)
HStack {
VStack(spacing: 10)
{
ForEach(launchPointCount, id: \.self) { item in
Text(item)
.font(.custom("Gill Sans", size: 10))
}
}.padding(.vertical)
GridStack(rows: launchPointCount.count, columns: targetCount.count) { row, col in
TextField("", text: $names[row][col]).border(Color.black, width: 0.5).background(Color.white).keyboardType(.decimalPad)
}.padding(7.5).background(Color.gray)
}.padding(.all, 5)
}.frame(maxWidth: .infinity)
}
}