[英]SwiftUI: NavigationLink is always activated when in a List
I can't prevent SwiftUI
's NavigationLink
from being activated when in a List
, I have this simple piece of code in which I need to do some kind of business check before deciding to show the details page or not (in a real world app, there might be some business logic happens inside the button's action):我无法阻止SwiftUI
的NavigationLink
在List
中被激活,我有一段简单的代码,在决定是否显示详细信息页面之前我需要进行某种业务检查(在真实世界的应用程序中,按钮的操作中可能会发生一些业务逻辑):
struct ContentView: View {
@State var showDetail = false
var body: some View {
NavigationView {
List {
Text("Text 1")
Text("Text 2")
Text("Text 3")
NavigationLink(destination: DetailView(), isActive: $showDetail) {
LinkView(showDetails: $showDetail)
}
}
}
}
}
struct LinkView: View {
@Binding var showDetails: Bool
var body: some View {
Button(action: {
self.showDetails = false
}) {
Text("Open Details")
}
}
}
struct DetailView: View {
var body: some View {
Text("Detail View")
}
}
how can I prevent navigation link from opening the details page in this case?在这种情况下,如何防止导航链接打开详细信息页面? and is this a bug in the SDK?这是 SDK 中的错误吗?
ps XCode version: 13.3.1
and iOS version (real device): 13.3.1
ps XCode 版本: 13.3.1
和 iOS 版本(真实设备): 13.3.1
Edit编辑
I can't replace List with ScrollView
because I have a ForEach
list of items in my real app, so don't post an answer considering using ScrollView
.我无法用ScrollView
替换 List 因为我的真实应用程序中有一个ForEach
项目列表,所以不要发布考虑使用ScrollView
的答案。
in a real world app, there might be some business logic happens inside the button's action在现实世界的应用程序中,按钮的操作中可能会发生一些业务逻辑
seems to be a little bit alogical.You can simply conditionally disable the link (and inform the user, that the link is unavailable by visual appearance)似乎有点不合逻辑。您可以简单地有条件地禁用链接(并通过视觉外观通知用户该链接不可用)
NavigationLink(...).disabled(onCondition)
where在哪里
func disabled(_ disabled: Bool) -> some View
Parameters参数
disabled残疾
A Boolean value that determines whether users can interact with this view.一个布尔值,用于确定用户是否可以与此视图交互。
Return Value返回值
A view that controls whether users can interact with this view.控制用户是否可以与此视图交互的视图。
Discussion讨论
The higher views in a view hierarchy can override the value you set on this view.视图层次结构中较高的视图可以覆盖您在此视图上设置的值。 In the following example, the button isn't interactive because the outer disabled(_:) modifier overrides the inner one:在下面的例子中,按钮不是交互式的,因为外部的 disabled(_:) 修饰符覆盖了内部的:
HStack {
Button(Text("Press")) {}
.disabled(false)
}
.disabled(true)
If I correctly understood your goal, it can be as follows如果我正确理解你的目标,它可以如下
List {
Text("Text 1")
Text("Text 2")
Text("Text 3")
LinkView(showDetails: $showDetail)
.background(
NavigationLink(destination: DetailView(), isActive: $showDetail) { EmptyView() })
}
and和
struct LinkView: View {
@Binding var showDetails: Bool
var body: some View {
Button(action: {
self.showDetails = true // < activate by some logic
}) {
Text("Open Details")
}
}
}
If you use.disable(true) it will reduce your list item opacity like a disabled button, to prevent this.如果您使用.disable(true),它将像禁用按钮一样降低您的列表项不透明度,以防止这种情况发生。 use below code style.使用下面的代码风格。 Use Navigation Link in backGround and check your navigation condition on Tap Gesture of your view.在背景中使用导航链接并在视图的点击手势上检查您的导航条件。
VStack{
List(0..<yourListArray.count, id: \.self) { index in
{
Text("\(yourListArr[index].firstName)")
}().onTapGesture{
let jobType = getFlags(jobsArr: yourListArray, index:index)
if jobType.isCancelledFlag == true{
self.shouldNavigate = false
}else{
self.shouldNavigate = true
}
}//Tap Gesture End
.background(NavigationLink(destination: YourDestinationView(),isActive: self.$shouldNavigate) {
}.hidden())}}//vStack
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.