我正在尝试创建一个按钮,它不仅可以导航到另一个视图,而且可以同时运行一个函数。我尝试将 NavigationLink 和按钮嵌入到堆栈中,但我只能单击按钮。
ZStack {
NavigationLink(destination: TradeView(trade: trade)) {
TradeButton()
}
Button(action: {
print("Hello world!") //this is the only thing that runs
}) {
TradeButton()
}
}
您可以使用 .simultaneousGesture 来做到这一点。 NavigationLink 将进行导航,同时执行完全按照您想要的操作:
NavigationLink(destination: TradeView(trade: trade)) {
Text("Trade View Link")
}.simultaneousGesture(TapGesture().onEnded {
print("Hello world!")
})
注意:这个答案是我刚接触 SwiftUI 时写的。我不再使用这种技术,因为我认为这是一个非常老套的解决方案。如果您的用例绝对需要它,您仍然可以使用它,但如果需要,请仔细测试您的应用程序。正如其他人提到的,这种技术在列表中不起作用。
您可以使用 NavigationLink(destination:isActive:label:)。使用绑定上的 setter 来了解链接何时被点击。我注意到可以在内容区域之外点击 NavigationLink,并且这种方法也可以捕获这些点击。
struct Sidebar: View {
@State var isTapped = false
var body: some View {
NavigationLink(destination: ViewToPresent(),
isActive: Binding<Bool>(get: { isTapped },
set: { isTapped = $0; print("Tapped") }),
label: { Text("Link") })
}
}
struct ViewToPresent: View {
var body: some View {
print("View Presented")
return Text("View Presented")
}
}
我唯一注意到的是设置器触发了三次,其中一次是在它被呈现之后。这是输出:
Tapped
Tapped
View Presented
Tapped
NavigationLink
+ isActive
+ onChange(of:)
// part 1
@State private var isPushed = false
// part 2
NavigationLink(destination: EmptyView(), isActive: $isPushed, label: {
Text("")
})
// part 3
.onChange(of: isPushed) { (newValue) in
if newValue {
// do what you want
}
}
这对我的自动取款机有用:
@State private var isActive = false
NavigationLink(destination: MyView(), isActive: $isActive) {
Button {
// run your code
// then set
isActive = true
} label: {
Text("My Link")
}
}
使用 NavigationLink(_:destination:tag:selection:) 初始值设定项并将模型的属性作为 selection 参数传递。因为它是双向绑定,所以您可以为此属性定义 didset 观察者,并在那里调用您的函数。
struct ContentView: View {
@EnvironmentObject var navigationModel: NavigationModel
var body: some View {
NavigationView {
List(0 ..< 10, id: \.self) { row in
NavigationLink(destination: DetailView(id: row),
tag: row,
selection: self.$navigationModel.linkSelection) {
Text("Link \(row)")
}
}
}
}
}
struct DetailView: View {
var id: Int;
var body: some View {
Text("DetailView\(id)")
}
}
class NavigationModel: ObservableObject {
@Published var linkSelection: Int? = nil {
didSet {
if let linkSelection = linkSelection {
// action
print("selected: \(String(describing: linkSelection))")
}
}
}
}
在此示例中,您需要将模型作为环境对象传递给 ContentView:
ContentView().environmentObject(NavigationModel())
在 SceneDelegate 和 SwiftUI 预览中。
模型符合ObservableObject协议,并且属性必须具有@Published属性。
(它在列表中工作)
我也刚刚用过:
NavigationLink(destination: View()....) {
Text("Demo")
}.task { do your stuff here }
iOS 15.3 部署目标。