Home > Software engineering >  How to pass different color when appending to an Array in SwiftUI?
How to pass different color when appending to an Array in SwiftUI?

Time:08-25

In my ContentView I have two buttons, red and green, when I click on each of them i change and then append them to an empty array that gets filled and display its items in my SecondView.

I would like to show a green name when i tap on the green button and a red one when i tap on the red button, how can i achieve this?

Here is the code:

ContentView

struct ContentView: View {
    @State private var names = ["Steve", "Bill", "Jeff", "Elon"]
    @State private var appearedNames = [String]()
    @State private var currentPerson: String?
    
    var body: some View {
        NavigationView {
            VStack {
                NavigationLink {
                    SecondView(appearedNames: $appearedNames)
                } label: {
                    Text("Change view")
                }
                
                HStack {
                    Button {
                        if currentPerson != nil {
                            appearedNames.append(currentPerson ?? "")
                        }
                        changePerson()
                    } label: {
                        Text(currentPerson ?? "Start")
                            .foregroundColor(currentPerson != nil ? .red : .black)
                            .font(.largeTitle)
                    }
                    
                    Button {
                        if currentPerson != nil {
                            appearedNames.append(currentPerson ?? "")
                        }
                        changePerson()
                    } label: {
                        Text(currentPerson ?? "Start")
                            .foregroundColor(currentPerson != nil ? .green : .black)
                            .font(.largeTitle)
                    }
                }
            }
        }
    }
    func changePerson() {
        if names.count > 0 {
            let index = Int.random(in: 0..<names.count)
            currentPerson = names[index]
            names.remove(at: index)
        }
    }
}

SecondView

struct SecondView: View {
    @Binding var appearedNames: [String]
    
    var body: some View {
        VStack {
            ForEach(appearedNames, id: \.self) { name in
                Text(name)
                    .font(.largeTitle)
                    .bold()
            }
        }
    }
}

CodePudding user response:

Instead of [String] store your choice in a struct with the chosen color:

// use this struct to save the chosen color with the name
struct ColoredName: Identifiable{
    let id = UUID()
    var name: String
    var color: Color
}

struct ContentView: View {
    @State private var names = ["Steve", "Bill", "Jeff", "Elon"]
    //change this to the appropriate type
    @State private var appearedNames = [ColoredName]()
    @State private var currentPerson: String?
    
    var body: some View {
        NavigationView {
            VStack {
                NavigationLink {
                    //pass the array on to the second view
                    SecondView(appearedNames: $appearedNames)
                } label: {
                    Text("Change view")
                }
                
                HStack {
                    Button {
                        if currentPerson != nil {
                            //Create and append your struct to the array
                            appearedNames.append(ColoredName(name: currentPerson ?? "", color: .red))
                        }
                        changePerson()
                    } label: {
                        Text(currentPerson ?? "Start")
                            .foregroundColor(currentPerson != nil ? .red : .black)
                            .font(.largeTitle)
                    }
                    
                    Button {
                        //Create and apped the struct to your array
                        if currentPerson != nil {
                            appearedNames.append(ColoredName(name: currentPerson ?? "", color: .green))
                        }
                        changePerson()
                    } label: {
                        Text(currentPerson ?? "Start")
                            .foregroundColor(currentPerson != nil ? .green : .black)
                            .font(.largeTitle)
                    }
                }
            }
        }
    }
    func changePerson() {
        if names.count > 0 {
            let index = Int.random(in: 0..<names.count)
            currentPerson = names[index]
            names.remove(at: index)
        }
    }
}

struct SecondView: View {
    //Change type here
    @Binding var appearedNames: [ColoredName]
    
    var body: some View {
        VStack {
            //itterating over the array will give you an instance of your struct
            ForEach(appearedNames) { person in
                //assign the name here
                Text(person.name)
                    //and the foreground color chosen
                    .foregroundColor(person.color)
                    .font(.largeTitle)
                    .bold()
            }
        }
    }
}
  • Related