ialyzaafan
ialyzaafan

Reputation: 398

Swiftui foreach looping on an array of buttons

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

Answers (1)

nine stones
nine stones

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

Related Questions