Create specified number of items in a list detailed by array

62 views Asked by At

I am wanting to enter a few details on one view.

main view

click a button "Let's go"

and it take me to my next view. In the next view i am passing some this information along with doing some calculations.

enter image description here

Easy part. ok. now the hard part for me.

you can see I entered "5" stands. I want my items in my list to say "Stand 1, stand 2... up to Stand 5. I will need to then pull the list items by "id" and calculate something based on what i type in the textfield later but right now this is driving me nuts.

Code: Array:

struct Stand: Codable, Identifiable, Hashable {
    var id = UUID()
    let stand: String
    var area: String
    var speed: Int
    var rf: Int
}

Code for image "Image 2":

struct Speeds1View: View {
    let title: String
    let productArea: String
    let noStands: String
    let billetArea: String
    @Environment(\.dismiss) var dismiss

    var standCount: Int {
        let sc = Int(noStands) ?? 0
        return sc
    }
    @State private var stand = [Stand]()
    @State var txtspeedCurrent: String
    @State private var rF = ""
    @State private var standNo: Int = 0
    @State private var rFCalculated: Int = 0

    var body: some View {
        NavigationStack{
                ZStack{
                    List{
                        HStack(alignment: .center){
                            Spacer()
                        VStack(){
                                Text("# of Stands")
                                Text(self.noStands)
                                Text("Billet Area")
                                Text(self.billetArea)
                                Text("Product Area")
                                Text(self.productArea)
                                Text(" Reduction Ratio: \(RedRatio) : 1")
                                Text("Testing")
                                Text(" Ave. Area Red: \(AveAreaRed)%")
                            }
                            Spacer()
                        }
                        ForEach(0..<standCount, id: \.self) { standCount in
                            StandRowView(stand: "1", speedCurrent: $txtspeedCurrent, rfactor: rF)
                        }
                        .padding(.horizontal)
                        .listRowInsets(EdgeInsets())
                        .listRowSeparator(.hidden)
                    }
                }
                        .onAppear(){
                            standList()
                        }
        }
        .navigationBarTitleDisplayMode(.inline)
        .navigationTitle("Calculate Area, \(title)")
    }

    private func standList(){
        self.standNo += 1
        
        let u = Stand(id: UUID(), stand: "\(standNo)", area: "Area: \(1)", speed: 8, rf: rFCalculated)
        self.stand.append(u)
    }
}

B. Klein - yes! thank you. i do need these to be separated.

question...

my model:

import Foundation
import SwiftUI

struct Stand: Codable, Identifiable, Hashable {
    var id: String {
        return self.stand
    }
    var stand: String
    let area: String
    let speed: Int
    var rf: Int
}

my view:

variables:

@State var stands = [Stand]()
@State var txtspeedCurrent: String
@State private var rF = ""
@State private var standNo: Int = 0
@State private var rFCalculated: Int = 0

my array:

 ForEach(0..<standCount, id: $stands.stand) { standCount in
 StandRowView(stand: $stands.stand, speedCurrent: $txtspeedCurrent, rfactor: rF)
                    }

for the id: in my array. How come i cannot just use my "stand" from my "stands" array, which should be my id? then inside my row (StandRow) use stands.stand for the id to show on screen?

1

There are 1 answers

3
B. Klein On

I see that this question was already answered in a comment, but for completeness' sake I'm adding an answer. Benzy Neez is correct, the issue is that you're passing in stand: "1" when you should be passing in something related to the actual ForEach loop, like stand: "\(standCount + 1)". This is a minor nitpick, but if you are intending each stand to be unique based on the number of it, you should probably use the stand's number as the id, like below:

struct Stand: Codable, Identifiable, Hashable {
    var id: String {
        return self.stand
    }

    let stand: String
    var area: String
    var speed: Int
    var rf: Int
}

This will let you use the stand's number as its ID. It's better practice to use a property of a struct as the ID if they are intended to be unique rather than creating a UUID in addition to the unique variable that you're already storing.

Another suggestion, consider creating a ViewModel object and using @StateObject rather than storing many separate objects in state.

struct SpeedsViewModel {
    var stand = [Stand]()
    var txtspeedCurrent: String
    var rF = ""
    var standNo: Int = 0
    var rFCalculated: Int = 0
}

// ...

struct Speeds1View: View {
    // ...
    @StateObject viewModel: SpeedsViewModel
    // ...
}