skip to Main Content

Newbie in SwiftUI. When I select an item in the List below, it only triggers onTapGesture if I press the Text. If I press outside the Text but in the "cell" it doesn’t trigger. I would like it to be triggered, how ca I achieve this?

    List(viewModel.cities, id: .self, selection: $selection) { city in
                VStack {
                    Text(city)
.frame(maxWidth: .infinity alignment: .leading)
                }
                .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .leading)
                .onTapGesture {
                    if isFocusedFromTextField {
                        from = city
                    } else {
                        to = city
                    }
                }
            }

2

Answers


  1. If it is fine to ignore taps on an already selected row, you can use onChange(of: selection).

    // modify the List with this, not the list rows
    .onChange(of: selection) { city in
        if isFocusedFromTextField {
            from = city
        } else {
            to = city
        }
    }
    

    Otherwise, consider using a Button as the list rows instead. This still maintains the selectable nature of the list.

    Button {
        if isFocusedFromTextField {
            from = city
        } else {
            to = city
        }
    } label: {
        // replace this with a more complicated view if you want...
        Text(city)
    }
    // - style the button to look more like a Text if you want
    // - get rid of the selection @State if you don't need it
    // - if you do need the selection, you can style the buttons differently
    // depending on selected state, using listRowBackground etc.
    
    Login or Signup to reply.
  2. Add background in the VStack using .background(). Because except the text rest of the view area is blank, and blank area not taking tap gesture.

           List(cities, id: .self) { city in
                VStack {
                    Text(city)
                        .frame(maxWidth: .infinity, alignment: .leading)
                }
                .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .leading)
                .background()    //just add this line
                .onTapGesture {
                    print("tapped")
                }
            }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search