Reputation: 398
when press a button in the loop, its background color changes to red and when pressing another button its color also changes to red. but the remaining button is still red does not change to blue again. How can I only change the pressed button to red and have the other buttons change to blue?
struct Box: Identifiable {
var id: Int
var title: String
}
struct MainView: View {
let boxes:[Box] = [
Box(id: 0, title: "Home"),
Box(id: 1, title: "Subjects"),
Box(id: 2, title: "attendence"),
Box(id: 3, title: "H.W"),
Box(id: 4, title: "Quizes"),
Box(id: 5, title: "class schedule"),
Box(id: 6, title: "Exam Schedule"),
Box(id: 7, title: "Inbox"),
Box(id: 8, title: "Evalouation"),
]
@Binding var showMenu: Bool
var body: some View{
VStack {
ScrollView(.horizontal,showsIndicators: false){
HStack{
ForEach(boxes, id: \.id) {
box in
BoxView(box: box)
}
}
}
}.padding()
}
}
struct BoxView: View {
@State var selectedBtn: Int = 1
var box: Box
var body: some View{
Button(action: {
self.selectedBtn = self.box.id
}){
Text(box.title)
.foregroundColor(.white)
}
.frame(width: 130, height: 50)
.background(self.selectedBtn == self.box.id ? Color.red : Color.blue)
.cornerRadius(25)
.shadow(radius: 10)
.padding(10)
}
}
Upvotes: 1
Views: 8261
Reputation: 3438
This works:
1) Add a @State
to MainView keeping track of the selected button
2) Pass this state as a binding to BoxView
3) Change @State
to a @Binding
(= in-out state) on BoxView
struct MainView: View {
[...]
@Binding var showMenu: Bool
@State var selected = 0 // 1
var body: some View{
VStack {
ScrollView(.horizontal,showsIndicators: false){
HStack{
ForEach(boxes, id: \.id) { box in
BoxView(box: box, selectedBtn: self.$selected) // 2
}
}
}
}.padding()
}
}
struct BoxView: View {
var box: Box
@Binding var selectedBtn: Int // 3
var body: some View{
Button(action: {
self.selectedBtn = self.box.id
}){
Text(box.title)
.foregroundColor(.white)
}
.frame(width: 130, height: 50)
.background(self.selectedBtn == self.box.id ? Color.red : Color.blue)
.cornerRadius(25)
.shadow(radius: 10)
.padding(10)
}
}
Upvotes: 6