Search code examples
swiftuiswiftui-navigationlinkswiftui-navigationviewlazyvgrid

SwiftUI: Custom label in navigation link is greyed out


I'm trying to use my custom card view as label to navigation link. this navigation link is also a Grid item. The result is aenter image description here

My Card Code:

struct CityCard: View {
    var cityData: CityData
    
    var body: some View {
        VStack {
            Text("\(cityData.name)")
                .padding([.top], 10)
            Spacer()
            Image(systemName: cityData.forecastIcon)
                .resizable()
                .frame(width: 45, height: 45)
            Spacer()
            HStack(alignment: .bottom) {
                Text(String(format: "%.2f $", cityData.rate))
                    .padding([.leading, .bottom], 10)
                Spacer()
                Text(String(format: "%.2f °", cityData.degrees))
                    .padding([.trailing, .bottom], 10)
            }
        }.frame(width: 150, height: 150)
        .background(Color.blue)
            .cornerRadius(10)
            .navigationTitle(cityData.name)
    }
}

My List View:

struct CityList: View {
    var cities: [CityData]
    
    let columns = [
        GridItem(.flexible(minimum: 150, maximum: 150)),
        GridItem(.flexible(minimum: 150, maximum: 150))
        ]
    
    var body: some View {
        ScrollView {
            LazyVGrid(columns: columns, spacing: 20) {
                ForEach(self.cities) { item in
                    NavigationLink(destination: Text(item.name), label: {
                        CityCard(cityData: item)
                    })
                }
            }
        }
    }
}

someone has a solution why it gives me this opacity?

Update: The main contact view is: enter image description here


Solution

  • It's greyed out because you don't yet have a NavigationView in your view hierarchy, which makes it possible to actually navigate to a new view.

    You can, for example, wrap your ScrollView in a NavigationView:

    var body: some View {
        NavigationView {
            ScrollView {
                LazyVGrid(columns: columns, spacing: 20) {
                    ForEach(self.cities) { item in
                        NavigationLink(destination: Text(item.name), label: {
                            CityCard(cityData: item)
                        })
                    }
                }
            }
        }
    }
    

    Or, if it's only happening in your preview, add a NavigationView to your preview code:

    NavigationView {
      CityList(...)
    }
    

    Keep in mind that if you have the default accent color (blue, in light mode) that your links will become invisible (since they will be blue) on top of the blue background. You can set a custom accent color in your project or via the accentColor modifier:

    NavigationView {
        //content
    }.accentColor(.black)