如何有条件地调用 SwiftUI NavigationLink?
How to call SwiftUI NavigationLink conditionally?
我在考虑如何在用户点击时有条件地允许启动 NavigationLink
。在 UIKit
中很明显,但在 SwiftUI
中这对我来说是个大问题。我知道我可以在我认为的某个地方声明 NavigationLink
即
@State private var isFired = false
/* (...) */
NavigationLink(destination: AnotherView(), isActive: $isFired) { EmptyView() }
然后这样称呼它
Button(action: {
if /* check condition */ {
self.isFired = true
} else {
print("condition is not fulfilled")
}
}) {
Image("my-image")
}
但是...问题是:我的导航 link 是在循环中动态创建的,并且将图像包装在 ScrollView
中,即
ScrollView(.vertical) {
ForEach(photos, id: \.self) { element in
NavigationLink(destination: ImagePreviewView(photo: element)) {
Image(uiImage: element.image)
}
}
}
如何在上面的代码中有条件地允许启动导航link?例如:用户点击图像 -> 出现密码请求 -> 如果密码正确,则导航 link 触发,如果不正确,应用程序会执行其他操作(显示警报等。无关紧要)
无论如何它应该是一个按钮...类似于
ScrollView(.vertical) {
ForEach(photos, id: \.self) { element in
Button(action: {
// here call a function with callback provided if password
// verification passed
self.checkPassword { verified in
if verified {
self.photo = element // store tapped element
self.isFired = true // << this might be called async
}
}
}) {
Image(uiImage: element.image)
}
}
}
.background(
// activate link for tapped photo
NavigationLink(destination: ImagePreviewView(photo: self.photo),
isActive: $isFired) { EmptyView() }
)
我在考虑如何在用户点击时有条件地允许启动 NavigationLink
。在 UIKit
中很明显,但在 SwiftUI
中这对我来说是个大问题。我知道我可以在我认为的某个地方声明 NavigationLink
即
@State private var isFired = false
/* (...) */
NavigationLink(destination: AnotherView(), isActive: $isFired) { EmptyView() }
然后这样称呼它
Button(action: {
if /* check condition */ {
self.isFired = true
} else {
print("condition is not fulfilled")
}
}) {
Image("my-image")
}
但是...问题是:我的导航 link 是在循环中动态创建的,并且将图像包装在 ScrollView
中,即
ScrollView(.vertical) {
ForEach(photos, id: \.self) { element in
NavigationLink(destination: ImagePreviewView(photo: element)) {
Image(uiImage: element.image)
}
}
}
如何在上面的代码中有条件地允许启动导航link?例如:用户点击图像 -> 出现密码请求 -> 如果密码正确,则导航 link 触发,如果不正确,应用程序会执行其他操作(显示警报等。无关紧要)
无论如何它应该是一个按钮...类似于
ScrollView(.vertical) {
ForEach(photos, id: \.self) { element in
Button(action: {
// here call a function with callback provided if password
// verification passed
self.checkPassword { verified in
if verified {
self.photo = element // store tapped element
self.isFired = true // << this might be called async
}
}
}) {
Image(uiImage: element.image)
}
}
}
.background(
// activate link for tapped photo
NavigationLink(destination: ImagePreviewView(photo: self.photo),
isActive: $isFired) { EmptyView() }
)