Swiftui 如何在 foreach 循环中对整行使用 Tap Gesture

Posted

技术标签:

【中文标题】Swiftui 如何在 foreach 循环中对整行使用 Tap Gesture【英文标题】:Swiftui How can you use on Tap Gesture for entire row in a foreach loop 【发布时间】:2020-12-01 23:27:35 【问题描述】:

我现在正在创建一个从 API 获取数据的 SearchBar,以红色突出显示的文本(见下图)是我想要在点击时传递给我的 userDefault 字符串的内容。只要我点击突出显示的红色文本,这就是有效的,当您点击该行中的任何位置(例如空格)时是否可以获得该值?任何建议都会很棒。

@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 嵌入到 HStack 中并添加 Spacer() 以填充整个区域,然后放置 onTapGestureHStack,像这样:

    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()

或者你可以使用ZStack来做一个全视图背景并将onTapGesture放在ZStack上,添加.frame(maxWidth: .infinity) strong> 到 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)
            

【讨论】:

您可能需要在.onTapGesture 之前将.contentShape(Rectangle()) 附加到HStack/VStack。 第一个解决方案中的 Spacer() 可以解决问题!

以上是关于Swiftui 如何在 foreach 循环中对整行使用 Tap Gesture的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 SwiftUI 在 Xcode 中消除 foreach 循环的歧义

SwiftUI:如何在 ForEach 循环中不显示“case none”

SwiftUI:如何使用 ForEach 循环使用各种代码的各种结构?

如何在 SwiftUI 的 foreach 循环中设置切换状态

SwiftUI:如何根据 Picker 的值更新 ForEach 循环的范围

如何在swiftUI中的Foreach循环上显示除一项之外的图像?