Swiftui NavigationLink是否可以在导航到另一个视图的同时执行操作?

Swiftui NavigationLink是否可以在导航到另一个视图的同时执行操作?,swiftui,Swiftui,我正在尝试创建一个按钮,它不仅可以导航到另一个视图,还可以同时运行一个函数。我尝试将NavigationLink和按钮嵌入堆栈中,但只能单击按钮 ZStack { NavigationLink(destination: TradeView(trade: trade)) { TradeButton() } Button(action: { print("Hello world!") //this is the only t

我正在尝试创建一个按钮,它不仅可以导航到另一个视图,还可以同时运行一个函数。我尝试将NavigationLink和按钮嵌入堆栈中,但只能单击按钮

ZStack {
    NavigationLink(destination: TradeView(trade: trade)) {
        TradeButton()
    }
    Button(action: {
        print("Hello world!") //this is the only thing that runs
    }) {
        TradeButton()
    }
}

你可以用。同时手势来做。NavigationLink将导航并同时执行与您所需完全相同的操作:

NavigationLink(destination: TradeView(trade: trade)) {
                        Text("Trade View Link")
                    }.simultaneousGesture(TapGesture().onEnded{
                    print("Hello world!")
                })
使用NavigationLink(u:destination:tag: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))")
            }
        }
    }
}
在SceneDelegate和SwiftUI预览中

该模型符合ObserveObject协议,并且该属性必须具有@Published属性

(它在列表中工作)

您可以使用NavigationLink(目的地: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")
    }
}

NavigationLink
+
isActive
+
onChange(of:)


一种方法(可能还有其他方法)是从
TradeView
onAppear
修改器运行此函数。两个限制。。。。出现的顺序和
只能出现一次。我使用
onAppear
检查
工作表中的先决条件。它不会阻止视图(在您的例子中,
TradeView
出现,但它会执行一个函数。可能是奇妙解决方案的副本!我以前使用过许多人提出的“onAppear()”,但它会引起各种问题。但这很简单,也很干净。非常感谢。当用户单击“后退”时,有办法吗按钮返回到上一个视图,它可以传回一个变量?甚至强制刷新上一个视图?这似乎不适用于您有一个项目列表,并且它们位于NavigationLink父级!是否有其他人对此有任何运气?是的,如果您在列表中使用此技术,它将不起作用。谢谢。此解决方案n在接受的解决方案不起作用的列表中起作用
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
// 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
    }
}