Creating an Array of arrays of input swiftUI

Viewed 75

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. As you can see, no matter what I fill in for the first grid the second grid stays the same

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)
    }
    
}
0 Answers
Related