Swiftui Как вы можете использовать жест нажатия для всей строки в цикле foreach

#ios #swift #swiftui #swiftui-view

#iOS #swift #swiftui #swiftui-просмотр

Вопрос:

Прямо сейчас я создаю панель поиска, которая получает данные из API, текст, выделенный красным (см. Изображение Ниже), — это то, что я хочу передать в свою строку по умолчанию при нажатии. Это работает до тех пор, пока я нажимаю на выделенный красным текст, возможно ли получить это значение, когда вы нажимаете в любом месте этой строки, например, на пробел? любые предложения были бы замечательными.

 @State var model: [SearchModel]
var defaults = UserDefaults.standard
@State var isOpen: Bool = false
 

Выше приведены мои переменные состояния и мое пользовательское значение по умолчанию. Я не буду показывать весь код, поскольку проблема связана только с приведенным ниже. Как вы можете видеть, мои значения находятся в foreach, я просто хочу, чтобы это было так, чтобы, если пользователь нажмет на пробел строки, я все равно мог выполнить этот код.

                      .onTapGesture {
                                      isOpen = true
                                     // I set the value here
                                    defaults.setValue(value.name, forKey: "location") 
                                }.fullScreenCover(isPresented: $isOpen, content: MainView.init)
 

Приведенный выше код дает мне правильное значение, но оно привязано к тексту

        ZStack {
                Color(UIColor.white)
                    .ignoresSafeArea()
                ScrollView(showsIndicators: false) {
                    LazyVStack {
                        ForEach(model) { value in
                            VStack(alignment: .leading) {
                                HStack {
                                    Text(value.name)
                                        .font(.system(size: 15))
                                        .background(Color.red)
                                        .padding(.trailing, 10.0)
                                        .onTapGesture {
                                            isOpen = true
                        // I set the value here
                                            defaults.setValue(value.name, forKey: "location") 
                                        }.fullScreenCover(isPresented: $isOpen, content: MainView.init)
                          
                                }
                                HStack {
                                    Text(value.statelong)
                                        .foregroundColor(Color.gray)
                                        .font(.system(size: 13))
                                    Spacer()
                                }
                                
                            }
                            VStack {
                                Spacer()
                                Divider()
                            }
                            
                        }
                        
                        
                    }.padding(.leading, 20.0)
                    
                    
                }
                
            }
            .listRowInsets(.none)
 

введите описание изображения здесь

Ответ №1:

Это работает только для выделенного текста, потому onTapGesture что он находится в текстовом представлении.

1. Используя HStack()

Я бы вставил VStack в a HStack и добавил a Spacer() , чтобы заполнить всю область, а затем поместил onTapGesture в HStack , вот так:

     ForEach(model) { value in
                HStack{
                    VStack(alignment: .leading) {
                        HStack {
                            Text(value.name)
                                .font(.system(size: 15))
                                .background(Color.red)
                                .padding(.trailing, 10.0)
                        }
                        HStack {
                            Text(value.statelong)
                                .foregroundColor(Color.gray)
                                .font(.system(size: 13))
                            Spacer()
                        }
                        
                    }
                    Spacer()
                }.contentShape(Rectangle())
                .onTapGesture {
                    isOpen = true
                    defaults.setValue(value.name, forKey: "location")
                }.fullScreenCover(isPresented: $isOpen, content: MainView.init)
            }
 

2. Использование ZStack()

Или вы могли бы использовать a ZStack , чтобы создать фон для полного просмотра и поместить onTapGesture на ZStack , добавить .frame(maxWidth: .infinity) к ZStack , чтобы заполнить всю доступную ширину, вот так:

  ForEach(model) { value in
                ZStack {
                    VStack(alignment: .leading) {
                        HStack {
                            Text(value.name)
                                .font(.system(size: 15))
                                .background(Color.red)
                                .padding(.trailing, 10.0)
                        }
                        HStack {
                            Text(value.statelong)
                                .foregroundColor(Color.gray)
                                .font(.system(size: 13))
                            Spacer()
                        }
                        
                    }
                    Spacer()
                }.contentShape(Rectangle())
                .frame(maxWidth: .infinity)
                .onTapGesture {
                    isOpen = true
                    defaults.setValue(value.name, forKey: "location")
                }.fullScreenCover(isPresented: $isOpen, content: MainView.init)
            }
 

Комментарии:

1. Вероятно, вам нужно было подключиться .contentShape(Rectangle()) к HStack / VStack раньше .onTapGesture .

2. Разделитель () в первом решении делает свое дело!