SwiftUI:单击导航链接时如何执行其他工作?

SwiftUI:单击导航链接时如何执行其他工作?,swiftui,Swiftui,现在我有一个导航链接 NavigationView{ 导航链接(目标:另一个视图()){ 文本(“单击此处”) } } .navigationBarTitle(“SwiftUI”)接受绑定的NavigationLink有重载。您可以使用绑定初始化它,并在setter中发出副作用,或者类似地,您可以使用具有某些@Published属性的模型,只需订阅其内部发布服务器即可。以下是一个既可以执行以下操作的示例: class Model: ObservableObject { @Published

现在我有一个导航链接

NavigationView{
导航链接(目标:另一个视图()){
文本(“单击此处”)
}
}

.navigationBarTitle(“SwiftUI”)
接受
绑定的
NavigationLink
有重载。您可以使用绑定初始化它,并在setter中发出副作用,或者类似地,您可以使用具有某些
@Published
属性的模型,只需订阅其内部发布服务器即可。以下是一个既可以执行以下操作的示例:

class Model: ObservableObject {
  @Published var isLinkActive = false
  var subscriptions = Set<AnyCancellable>()
  init() {
    $isLinkActive
      .sink { _ in
        print("I'm a side effect in the model")
      }
    .store(in: &subscriptions)
  }
}

struct ContentView: View {
  @ObservedObject var model: Model
  let isLinkActive: Binding<Bool>
  init(model: Model = .init()) {
    self.model = model
    self.isLinkActive = Binding<Bool>(
      get: { [model] in model.isLinkActive},
      set: { [model] in
        print("I'm a side effect in the binding!")
        model.isLinkActive = $0
    })
  }
  var body: some View {
    NavigationView {
      NavigationLink("hello", destination: Color.red, isActive: isLinkActive)
    }
  }
}
类模型:ObservableObject{
@已发布的变量isLinkActive=false
var subscriptions=Set()
init(){
$isLinkActive
.sink{uuuu in
打印(“我是模型中的副作用”)
}
.store(位于:&订阅中)
}
}
结构ContentView:View{
@观测对象var模型:模型
让IsLink处于活动状态:绑定
init(模型:model=.init()){
self.model=model
self.isLinkActive=绑定(
获取:{model.isLinkActive}中的[model],
集合:{[model]在
打印(“我是装订的副作用!”)
model.isLinkActive=$0
})
}
var body:一些观点{
导航视图{
导航链接(“你好”,目的地:Color.red,isActive:isLinkActive)
}
}
}

对于您描述的场景,这里是最简单的方法

NavigationView {
     NavigationLink("Click Here", destination: 
         AnotherView()
             .onAppear {
                 // any action having access to current view context
             })
}

SwiftUI并没有提供一种简单的方法来实现这一点,但它确实提供了一种方法。您应该使用一个
按钮
,其操作会触发
导航链接

问题是这样做的代码既麻烦又难看。因此,我编写了一个控件,将其包装成类似于
按钮
导航链接
的爱子控件

struct ActionNavigationLink:视图{
私人出租目的地:目的地
私人出租内容:内容
私有let操作:(NavigationToken)->()
@状态私有变量continueToDestination:Bool=false
初始化(
目的地:目的地,
操作:@escaping(NavigationToken)->(),
@ViewBuilder内容:()->内容
) {
self.destination=目的地
行动
self.content=content()
}
var body:一些观点{
按钮(操作:按钮操作,标签:{content})
.背景(
导航链接(
目的地:目的地,
isActive:$continueToDestination,
标签:{EmptyView()}
)
)
}
私有函数按钮操作(){
let token=NavigationToken{
self.continueToDestination=true
}
行动(令牌)
}
}
NavigationToken
是一个非常简单的结构,可以执行操作。该操作定义了一旦触发将如何执行导航

struct NavigationToken{
私有let导航操作:()->()
fileprivate init(u操作:@escaping()->()){
self.navigationAction=操作
}
func导航(){
导航操作()
}
}
此令牌将传递给您在使用此控件时提供的操作,以便在实际执行导航时为您提供完全权限。因此,如果您需要执行一些API调用,并且只在回调返回后导航,那么您完全可以实现这一点

在这里,我通过将导航延迟3秒来模拟API调用

ActionNavigationLink(
目标:EmptyView(),
操作:{中的令牌
DispatchQueue.main.asyncAfter(截止日期:.now()+秒(3)){
token.navigate()
}
}
) {
文本(“延迟导航”)
}

可以在上找到完整的源代码。

是否要打开其他视图()如详细视图?。您的代码有什么问题?我想在打开另一个视图()之前和单击NavigationLink之后创建一个对象并将其添加到数据库中。我不知道怎么做。你可以在另一个视图()中装箱并保存你的对象。onAppear(){}或在你的主视图文本(“Clik here”)。手势(Tap手势()创建并保存到对象…@ErnistIsabekov这很有帮助,谢谢!