在列表行中的任意位置点击导航 link 被触发,有什么方法可以改变这种行为吗?

On tap anyplace in List row the navigation link is triggered, have some way to change this behavior?

我在 iOS 14 中使用 Scrollview + LazyVStack 创建列表,在 iOS 13 中使用列表,但点击行为不同。如果我将 NavigationLink 放在 LazyVStack 中,link 仅在点击时触发,但在列表中,如果我点击行中的任何位置,则会触发 NavigationLink。

有没有办法只有在点击列表时才触发列表中的某些 NavigationLink?下面这段代码是一个例子,实际项目中组件里面有很多组件,不是简单的把导航link放在列表外面。

代码:

列表屏幕

import SwiftUI

struct ContentView: View {
    
    @State var navigate = false
    
    var body: some View {
        NavigationView {
            VStack {
                VList {
                    ForEach(0..<3) { index in
                        VStack(alignment: .leading) {
                            HStack {
                                Text("Item title")
                                    .font(.system(size: 17))
                                    .fontWeight(.semibold)
                                    .frame(idealWidth: .infinity, maxWidth: .infinity, alignment: .leading)
                                    .padding(.all, 4)
                                
                                ZStack {
                                    Text("See more")
                                        .font(.system(size: 15))
                                        .underline()
                                        .padding(.all, 4)
                                        .onTapGesture {
                                            self.navigate = true
                                        }
                                    
                                    NavigationLink(
                                        destination: Text("Destination"),
                                        isActive: $navigate,
                                        label: {
                                            EmptyView()
                                        })
                                        .buttonStyle(PlainButtonStyle())
                                }
                            }
                            
                            Text("Description of item")
                        }
                    }
                }
            }
            .navigationBarHidden(true)
            .navigationBarTitle("")
        }
    }
}

VList 组件

import SwiftUI

struct VList<Content:View>: View {
    
    var content: () -> Content
    
    var body: some View {
        if #available(iOS 14.0, *) {
            ScrollView {
                LazyVStack(spacing: 0) {
                    content()
                }
            }
        } else {
            List {
                content()
                    .padding(.horizontal, -20)
            }
            .onAppear {
                UITableView.appearance().separatorStyle = .none
                UITableViewCell.appearance().selectionStyle = .none
            }
        }
    }
}

您必须为 VStack 提供背景并使用 onTapGesture。所以我不知道你的应用程序颜色或背景是什么我给了不可见的颜色,你可以用你的颜色替换它。另请注意,您应该告诉 SwiftUI 正在使用背景,这使得 SwiftUI 不会将操作应用于所有 VStack。


struct ContentView: View {
    
    @State var navigate = false
    
    var body: some View {
        NavigationView {
            VStack {
                List {
                    ForEach(0..<3) { index in
                        VStack(alignment: .leading) {
                            HStack {
                                Text("Item title")
                                    .font(.system(size: 17))
                                    .fontWeight(.semibold)
                                    .frame(idealWidth: .infinity, maxWidth: .infinity, alignment: .leading)
                                    .padding(.all, 4)
                                
                                ZStack {
                                    Text("See more")
                                        .font(.system(size: 15))
                                        .underline()
                                        .padding(.all, 4)
                                        .onTapGesture {
                                            self.navigate = true
                                        }
                                    
                                    NavigationLink(
                                        destination: Text("Destination"),
                                        isActive: $navigate,
                                        label: {
                                            EmptyView()
                                        })
                                        .buttonStyle(PlainButtonStyle())
                                }
                            }
                            
                            
                            Text("Description of item")
                        }
                        .background(Color.white.opacity(0.01).onTapGesture { })    // << : Here
                    }
                }
            }
            .navigationBarHidden(true)
            .navigationBarTitle("")
        }
    }
}