skip to Main Content

I created a vertical scrollview as below:


struct UserFeedView: View {
    
    var body: some View {
        @State var selectedFilter: Filter?
        
        let filters = [
        Filter(name: "All"),
        Filter(name: "fil1"),
        Filter(name: "fil2"),
        Filter(name: "fil3"),
        ]

        VStack() {
            ScrollView(.horizontal,showsIndicators: false) {
                HStack(spacing: 15) {
                    ForEach(filters) { filter in
                        Text(filter.name)
                            .font(.system(size: selectedFilter?.id == filter.id ? 30 : 20))
                            .onTapGesture {
                                selectedFilter = filter
                            }
                    }
                }
                .padding(.top, 10)
                .padding(.leading, 30)
            }
            .frame(height: 150)
            .onAppear {
               if let first = filters.first {
                   selectedFilter = first
               }
            }
            Spacer()
        }
    }
}

I am trying to change the font size of the selected item so the user can see what has been selected.

The goal is to :

When the user first access the screen, the first item is selected then when scrolling and selecting an item, the selected item has an increased size and bold compared to the other item.

Any idea?
thanks

2

Answers


  1. Assuming Filter is Identifiable:

    struct Filter: Identifiable {
        let name: String
        var id: String { name }
    }
    

    You can add a @State to your view that indicates which filter is selected.

    // here I'm assuming "filters" is a global constant.
    // if it is part of "self", then you would need to initialise it in onAppear
    @State var selectedFilterId = filters[0].id
    

    Then it is just a matter of showing different views depending on whether the filter is the selected one:

    ForEach(filters) { filter in
        if filter.id == selectedFilterId {
            Text(filter.name)
                .font(.system(size: 30))
                .bold()
                .onTapGesture {
                    selectedFilterId = filter.id
                }
        } else {
            Text(filter.name)
                .onTapGesture {
                    selectedFilterId = filter.id
                }
        }
    }
    

    You can extract the common onTapGesture by adding a Group:

    Group {
        if filter.id == selectedFilterId {
            Text(filter.name)
                .font(.system(size: 30))
                .bold()
        } else {
            Text(filter.name)
        }
    }.onTapGesture {
        selectedFilterId = filter.id
    }
    
    Login or Signup to reply.
  2. You could try something simple like this:

    In this example code, tapping on a Filter name in the scrollview, increases the
    font size of the tapped Filter to 30, leaving the other entries of size 20.

    The code also shows, that the first Filter is selected
    (font size 30) when the view first appear.

    struct ContentView: View {
        @State private var selected: Filter?   // <-- here
        let filters = [
            Filter(name: "All"),
            Filter(name: "fil1"),
            Filter(name: "fil2"),
            Filter(name: "fil3")]
        
        var body: some View {
            ScrollView(.horizontal,showsIndicators: false) {
                HStack(spacing: 15) {
                    ForEach(filters) { filter in
                        Text(filter.name)
                            .bold(selected?.id == filter.id)  // <-- here
                            .font(.system(size: selected?.id == filter.id ? 30 : 20))  // <-- here
                            .onTapGesture {
                                selected = filter  // <-- here
                            }
                    }
                }
                .padding(.top, 10)
                .padding(.leading, 30)
            }
            .frame(height: 150)
            .onAppear {
               if let first = filters.first {
                   selected = first   // <-- here
               }
            } 
        }
    }
    
    struct Filter: Identifiable {
        let name: String
        var id: String { name }
    }
    

    EDIT-1

    added .bold(selected?.id == filter.id) to have a bold appearance as well when selected.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search