Reuse styled NavigationLink for another destination

179 views Asked by At

I have styled a NavigationLink in a subview to reuse its styling again for other destinations.

This is the Code:

struct ContentView: View {  
    var body: some View {
        NavigationView {
            VStack {
                styledNavigationLink(background-color: .red, symbol: "flame.fill", textlabel: "Great Stuff", nextDestination: "secondView()")
                styledNavigationLink(background-color: .blue, symbol: "snow", textlabel: "Cold Stuff", nextDestination: "thirdView()")
            }
        }
    }
}


struct styledNavigationView: View {
    @State var background-color: Color
    @State var symbol: String
    @State var textlabel: String
    @State var nextDestination: String
    
    var body: some View {
        NavigationLink(destination: nextDestination, label: {
            VStack {
                Image(systemName: symbol).foregroundColor(.white)
                Text(textlabel)
                    .foregroundColor(.white)
            }
        })
        .frame(width: 300, height: 75, alignment: .center)
        .padding(.all, 20)
        .background(background-color)
        .cornerRadius(10)
        .shadow(radius: 10)
    }
}

The styling works great, but I don't know how to implement the new destination. I doesn't work with a string as type.

1

There are 1 answers

3
Asperi On

You need to make styled navigation link as generic by destination.

Here is possible solution (with some replications). Tested with Xcode 11.4 / iOS 13.4.

struct ContentView: View {
    var body: some View {
        NavigationView {
            VStack {
                styledNavigationLink(background_color: .red, symbol: "flame.fill", textlabel: "Great Stuff", nextDestination: secondView())
                styledNavigationLink(background_color: .blue, symbol: "snow", textlabel: "Cold Stuff", nextDestination: thirdView())
            }
        }
    }
}

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

struct thirdView: View {
    var body: some View {
        Text("Third")
    }
}

// By the way, states in below view is not needed as they currently done
struct styledNavigationLink<Destination: View>: View {
    var background_color: Color
    var symbol: String
    var textlabel: String
    var nextDestination: Destination

    var body: some View {
        NavigationLink(destination: nextDestination, label: {
            VStack {
                Image(systemName: symbol).foregroundColor(.white)
                Text(textlabel)
                    .foregroundColor(.white)
            }
        })
        .frame(width: 300, height: 75, alignment: .center)
        .padding(.all, 20)
        .background(background_color)
        .cornerRadius(10)
        .shadow(radius: 10)
    }
}