Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible for a NavigationLink to perform an action in addition to navigating to another view?

Tags:

swiftui

I'm trying to create a button that not only navigates to another view, but also run a function at the same time. I tried embedding both a NavigationLink and a Button into a Stack, but I'm only able to click on the Button.

ZStack {
    NavigationLink(destination: TradeView(trade: trade)) {
        TradeButton()
    }
    Button(action: {
        print("Hello world!") //this is the only thing that runs
    }) {
        TradeButton()
    }
}
like image 334
Jnguyen22 Avatar asked Aug 27 '19 01:08

Jnguyen22


People also ask

What is NavigationLink?

A view that controls a navigation presentation.

What is NavigationLink in SwiftUI?

NavigationLink in SwiftUI allows pushing a new destination view on a navigation controller. You can use NavigationLink in a list or decide to push a view programmatically. The latter enables you to trigger a new screen from a different location in your view.


2 Answers

You can use .simultaneousGesture to do that. The NavigationLink will navigate and at the same time perform an action exactly like you want:

NavigationLink(destination: TradeView(trade: trade)) {                         Text("Trade View Link")                     }.simultaneousGesture(TapGesture().onEnded{                     print("Hello world!")                 }) 
like image 187
Nguyễn Khắc Hào Avatar answered Sep 19 '22 21:09

Nguyễn Khắc Hào


You can use NavigationLink(destination:isActive:label:). Use the setter on the binding to know when the link is tapped. I've noticed that the NavigationLink could be tapped outside of the content area, and this approach captures those taps as well.

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")
    }
}

The only thing I notice is that setter fires three times, one of which is after it's presented. Here's the output:

Tapped
Tapped
View Presented
Tapped
like image 22
sramhall Avatar answered Sep 18 '22 21:09

sramhall