SwiftUI add border to onSelect horizontal Scrollview image

886 Views Asked by At

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!)
           }
        }
     }
}
1

There are 1 best solutions below

0
On

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.