Mert Köksal
Mert Köksal

Reputation: 901

Change Selected Button Color SwiftUI ForEach Array

I have an array of items and I want to change its foreground color when tapped. Right now with the below code all of them are changing to blue. How should I modify it?

    struct HorizontalCardSelector: View {
    @State var selected = 0
    @State var items: [String] = ["Visa", "MasterCard", "PayPal"]
    var body: some View {
        ScrollView(.horizontal, showsIndicators: false) {
            HStack(spacing: 17) {
                ForEach(items, id: \.self) { item in
                    Button(action: {
                        self.selected = items.firstIndex(of: item)!
                        print("item \(item) tapped")
                    }, label: {
                        Text(item)
                            .foregroundColor(self.selected == selected ? .blue: .black)
                            .fontWeight(.semibold)
                    })
                }
            }
        }
        .padding(.vertical)
    }
}

Upvotes: 1

Views: 1588

Answers (2)

Tushar Sharma
Tushar Sharma

Reputation: 2882

You can maintain a boolean state array, that hold tapped state for each item in items array. Then you can toggle state between true and false.

import SwiftUI

struct HorizontalCardSelector: View {
    @State var selected :[Bool]
    @State var items: [String]
    
    init(item:[String]) {
        _items = State(wrappedValue: item)
        _selected = State(wrappedValue: [Bool](repeating: false, count: item.count))
    }
    var body: some View {
        ScrollView(.horizontal, showsIndicators: false) {
            HStack(spacing: 17) {
                ForEach(0..<items.count, id: \.self) { index in
                    Button(action: {
                        if self.selected[index] == true{
                            self.selected[index] = false
                        }else{
                            self.selected[index] = true
                        }
                       
                        print("item \(items[index]) tapped")
                    }, label: {
                        Text(items[index])
                            .foregroundColor(selected[index] ? .blue: .black)
                            .fontWeight(.semibold)
                    })
                }
            }
        }
        .padding(.vertical)
    }
}

@main

struct WaveViewApp: App {
    var body: some Scene {
        WindowGroup {
            HorizontalCardSelector(item: ["Visa", "MasterCard", "PayPal"])
        }
    }
}

Array initialisation depends on your requirement.You can perform from child view as well.

Upvotes: 1

jnpdx
jnpdx

Reputation: 52575

Change your selected variable to an Optional string. Then, compare whether or not the current item is equal to the selected variable.

struct ContentView: View {
    @State var selected : String? // <-- Here
    @State var items: [String] = ["Visa", "MasterCard", "PayPal"]
    var body: some View {
        ScrollView(.horizontal, showsIndicators: false) {
            HStack(spacing: 17) {
                ForEach(items, id: \.self) { item in
                    Button(action: {
                        self.selected = item  // <-- Here
                        print("item \(item) tapped")
                    }, label: {
                        Text(item)
                            .foregroundColor(self.selected == item ? .blue: .black)  // <-- Here
                            .fontWeight(.semibold)
                    })
                }
            }
        }
        .padding(.vertical)
    }
}

Upvotes: 4

Related Questions