2

I tried to make a horizontal scrollview that contained a list of item. when I clicked any of the item, it will show a border(highlight) behind the item. When I press another item, the previous border disappear and the latest clicked item appear the border. It just looks like a selection horizontal scrollview. I have no idea about how to do so.

ScrollView(.horizontal, showsIndicators: false){
    LazyHStack{
        ForEach(self.staffs.indices, id: \.self){ staff in
           VStack{
                Image(staff.image)
                .resizable()
                .frame(width: 100, height: 100)
                .clipShape(Circle())
           }
           .onTapGesture {
                 print(createBookingJSON.staffs[staff].staffID!)
           }
        }
     }
}
Oxford212
  • 89
  • 1
  • 8
  • You need to track selection in state, review this topic for demo https://stackoverflow.com/questions/63297201/how-to-select-an-item-in-scrollview-with-swiftui. – Asperi Dec 11 '20 at 07:38
  • Convert your VStack into a standalone view, then pass a Binding to it that can be read from the Parent View. I will post an answer shortly. – DaWiseguy Dec 11 '20 at 07:39

1 Answers1

4

Convert your VStack into a standalone view, then pass a Binding to it that can be read from the Parent View. Your new VStack standalone view needs an OnTapGesture or an Action through a button to toggle it's state. We will make your ForEach a "single selection" list as you request.

NEW View to use inside your ForEach:

struct ItemCell: View {
    var item: Item
    @Binding var selectedItem: Item?

    var body: some View {
        VStack{
                Image(item.image)
                .resizable()
                .frame(width: 100, height: 100)
                .border(Color.green, width: (item == selectedItem) ? 20 : 0)
           }
           .onTapGesture {
                 self.selectedItem = item
                 print(createBookingJSON.staffs[staff].staffID!)
           }
       }
    }

Now in the view that contains your Foreach, add a State Var of selectedItem so you can read the Binding you created in your cells. And Replace your VStack with your new ItemCell:

struct YourParentView: View {
    @State var selectedItem: Item? = nil
        
    var body: some View {
        ScrollView(.horizontal, showsIndicators: false){
            LazyHStack{
                ForEach(self.staffs.indices, id: \.self){ staff in
                   ItemCell(item: staff, selectedItem: self.$selectedItem)
                }
             }
        }
    }
}

Now when you click on the item, a border should appear. You may need to play with the border depending on your design, and the clipShape you have used of Circle(). Good Luck comrade.

DaWiseguy
  • 786
  • 7
  • 16