Swift reusable NavigationLink

Viewed 156

I have the following in my View where the formatting of the NavigationLink is the same for several. I want to be able to reduce duplication and reuse the same for each. I've seen this done for buttons but cannot find an answer for NavigationLinks - is this possible in a similar way?

NavigationLink(destination: FairRentView(viewModel: FairRentViewModel(Amounts(), housemates: 1)))
                {
                    Text("1")
                        .fontWeight(.bold)
                        .font(.title)
                        .lineLimit(0)
                        .padding()
                        .frame(minWidth: 0, maxWidth: 250, alignment: .center)
                        .background(gradient)
                        .foregroundColor(.white)
                        .padding(2)
                        .overlay(
                            RoundedRectangle(cornerRadius:20)
                                .stroke(gradient, lineWidth:15)
                        )
                        .overlay(
                            Image(systemName: "person.crop.circle.badge.plus")
                                .font(.largeTitle)
                                .padding(.leading)
                                .foregroundColor(.white)
                            , alignment: .leading)
                        .padding(5)
                    
                }
                NavigationLink(destination: FairRentView(viewModel: FairRentViewModel(Amounts(), housemates: 2)))
                {
                    Text("2")
                        .fontWeight(.bold)
                        .font(.title)
                        .padding()
                        .frame(minWidth: 0, maxWidth: 250, alignment: .center)
                        .background(gradient)
                        .foregroundColor(.white)
                        .padding(2)
                        .overlay(
                            RoundedRectangle(cornerRadius:20)
                                .stroke(gradient, lineWidth:15)
                        )
                        .overlay(
                            Image(systemName: "person.crop.circle.badge.plus")
                                .font(.largeTitle)
                                .padding(.leading)
                                .foregroundColor(.white)
                            , alignment: .leading)
                        .padding(5)
                }
1 Answers

You can use modifier in extension, like below

extension Text {
    func styledLinkLabel<V: View & ShapeStyle>(with gradient: V) -> some View {
        self.fontWeight(.bold)
            .font(.title)
            .padding()
            .frame(minWidth: 0, maxWidth: 250, alignment: .center)
            .background(gradient)
            .foregroundColor(.white)
            .padding(2)
            .overlay(
                RoundedRectangle(cornerRadius:20)
                    .stroke(gradient, lineWidth:15)
            )
            .overlay(
                Image(systemName: "person.crop.circle.badge.plus")
                    .font(.largeTitle)
                    .padding(.leading)
                    .foregroundColor(.white)
                , alignment: .leading)
            .padding(5)
    }
}

and apply it

NavigationLink(destination: FairRentView(viewModel: FairRentViewModel(Amounts(), housemates: 2)))
{
    Text("2")
        .styledLinkLabel(with: gradient)
}
Related