Is there a way to add an extra function to NavigationLink? SwiftUI
Asked Answered
T

2

13

I would like to add an extra function to the NavigationLink.

example code is something like this:

struct ContentView: View {

func yes () {
print("yes")
}

var body: some View {

NavigationView {
NavigationLink(destination: level1()) {

     Text("Next")      
}}}}

I know this doesn't work, but is it possible to do something like this? (It will go to the destination and call the function at the same time)

NavigationLink(destination: level1(), yes()) {Text("Next")}   

I tried putting a button inside the NavigationLink but it didn't work either. When I do this only the function in the button works, NavigationLink doesn't.

NavigationLink(destination: level1())   {
        Button(action: { self.yes() }) 
        { Text("Button")}
        }
Tax answered 5/3, 2020 at 15:37 Comment(1)
Couldn’t u pass the method as a closure to the destination view in the initFreak
L
33

Use the onAppear(perform:). This will perform some function on a View's appear.

struct ContentView: View {
    var body: some View {
        NavigationView {
            NavigationLink(destination: DetailView().onAppear {
                self.someFunc()
            }) {
                Text("First Screen")
            }
        }
    }

    func someFunc() {
        print("Click")
    }
}

struct DetailView: View {
    var body: some View {
        Text("Second Screen")
    }
}

Lipid answered 5/3, 2020 at 15:51 Comment(5)
You're right, I can use onAppear in NavigationLink and the DetailView anyway. Thanks!Tax
the .onAppear on the NavigationLink is spot on. This is a simple solution to many other overly complex solutions proposed out there to perform and action on a View. In a way sort of a way to get a viewdidappear under Swift.Beforehand
in iOS 15 I get glitches - navigation view programmatically taps back button and reorders list elements. I cannot recommend the solutionVandalism
@Vandalism Might be. This solution was for iOS 13 originally. Please let me know, which way would be better for iOS 15?Lipid
@AlekseyPotapov I posted a solution to this question.Vandalism
V
1

Solution for SwiftUI, iOS 15.1 & Xcode 13.1.

import Foundation
import SwiftUI

// NavigationLink replacement with action
// Usage:
//var body: some View {
//    NavigationButton(
//        action: { print("tapped!") },
//        destination: { Text("Pushed View") },
//        label: { Text("Tap me") }
//    )
//}

struct NavigationButton<Destination: View, Label: View>: View {
    var action: () -> Void = { }
    var destination: () -> Destination
    var label: () -> Label
    
    @State private var isActive: Bool = false
    
    var body: some View {
        Button(action: {
            self.action()
            self.isActive.toggle()
        }) {
            self.label()
                .background(
                    ScrollView { // Fixes a bug where the navigation bar may become hidden on the pushed view
                        NavigationLink(destination: LazyDestination { self.destination() },
                                       isActive: self.$isActive) { EmptyView() }
                    }
                )
        }
    }
}

// This view lets us avoid instantiating our Destination before it has been pushed.
struct LazyDestination<Destination: View>: View {
    var destination: () -> Destination
    var body: some View {
        self.destination()
    }
}

I cannot find the original code, but this solution worked for me perfectly.

Vandalism answered 24/11, 2021 at 16:9 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.