在列表行中的任意位置点击导航 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("")
}
}
}
我在 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("")
}
}
}