Swiftui foreach 在按钮数组上循环

ial*_*fan 1 foreach xcode button swift swiftui

当按下循环中的一个按钮时,其背景颜色变为红色,当按下另一个按钮时,其颜色也变为红色。但剩下的按钮仍然是红色的,不会再次变成蓝色。如何只将按下的按钮更改为红色,而将其他按钮更改为蓝色?

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)

    }
}
Run Code Online (Sandbox Code Playgroud)

nin*_*nes 6

这有效:

1)添加一个@State到MainView来跟踪所选按钮

2) 将此状态作为绑定传递给 BoxView

3) 在 BoxView 上更改@State@Binding(= in-out 状态)

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)
  }
}
Run Code Online (Sandbox Code Playgroud)