Variable for DestinationView

    var body: some View {
        VStack {
            List {
                ForEach(starSigns) {ZodiacSign in
                    NavigationLink(destination: ZodiacSign.DestinationView) {
                        Text(ZodiacSign.Symbol)
                        Text(ZodiacSign.name)
                    }
                }
            }
        }
    }
}

I have this basic view which gets information from a list I created, but how do I get the destination view to work where an example of it would be AriesView(), I would like the destination to be there. Currently it comes up with an error of "Protocol 'View ' cannot conform to the protocol itself" Sorry for the complexity of this question, I was struggling to explain it.

THANK YOU IN ADVANCE!!!

Answered by Claude31 in 803275022

I would do it this way with ViewBuilder:

struct ZodiacSign: Identifiable {
    let id = UUID()
    var name: String
    var symbol: String      // as per Swift conventions, should start with lowercase
    // Replaced by ViewBuilder  var DestinationView: View
}

@ViewBuilder func zodiacDestination(name: String) -> some View {
    switch name {
        case "Aries"    : AriesView()
        case "Taurus"   : TaurusView()
        case "Gemini"   : GeminiView()
        case "Cancer"   : CancerView()
        case "Leo"      : LeoView()
        case "Virgo"    : VirgoView()
        case "Libra"    : LibraView()
        case "Scorpio"  : ScorpioView()
        case "Sagittarius": SagittariusView()
        case "Capricorn": CapricornView()
        case "Aquarius" : AquariusView()
        case "Pisces"   : PiscesView()
        default: EmptyView()
      }
  }

struct ContentView: View {

    @State var starSigns = [    // Need to be a State var
        ZodiacSign(name: "Aries", symbol: "♈︎"),  // DestinationView: AriesView()),
        ZodiacSign(name: "Taurus", symbol: "♉︎"), // DestinationView: TaurusView()),
        ZodiacSign(name: "Gemini", symbol: "♊︎"), // DestinationView: GeminiView()),
        ZodiacSign(name: "Cancer", symbol: "♋︎"), // DestinationView: CancerView()),
        ZodiacSign(name: "Leo", symbol: "♌︎"), // DestinationView: LeoView()),
        ZodiacSign(name: "Virgo", symbol: "♍︎"), // DestinationView: VirgoView()),
        ZodiacSign(name: "Libra", symbol: "♎︎"), // DestinationView: LibraView()),
        ZodiacSign(name: "Scorpio", symbol: "♏︎"), // DestinationView: ScorpioView()),
        ZodiacSign(name: "Sagittarius", symbol: "♐︎"), // DestinationView: SagittariusView()),
        ZodiacSign(name: "Capricorn", symbol: "♑︎"), // DestinationView: CapricornView()),
        ZodiacSign(name: "Aquarius", symbol: "♒︎"), // DestinationView: AquariusView()),
        ZodiacSign(name: "Pisces", symbol: "♓︎") // DestinationView: PiscesView())
    ]

    var body: some View {
        // VStack {
        NavigationView { // You have to put in a NavigationView
            List {
                ForEach(starSigns, id: \.id) {zodiacSign in   // should start with lowercase
                    NavigationLink(destination: zodiacDestination(name: zodiacSign.name)) {
                        Text(zodiacSign.symbol)
                        Text(zodiacSign.name)
                    }
                }
            }
        }
    }
}

struct AriesView: View {
    var body: some View {
        VStack {
            Text("♈︎ Aries is a constellation…")
        }
    }
}

struct TaurusView: View {
    var body: some View {
        VStack {
            Text("♉︎ Taurus is a constellation…")
        }
    }
}

struct GeminiView: View {
    var body: some View {
        VStack {
            Text("♊︎ Gemini is a constellation…")
        }
    }
}

When you post code, please post more so that we can better explain the solution.

So, show how stasSigns is defined and how each zodiacSign is defined in this structure.

A typical pattern would be:

struct ContentView : View {
        @ViewBuilder func destination(name: String) -> some View {
            switch name {
                case "aries": AriesView()
                // other case here
                default: EmptyView()
              }
          }

    var body: some View {
            List {
                ForEach(starSigns) {zodiacSign in  // zodiacSign should start with lowercase, as it is an instance
                    NavigationLink(destination: destination(name: zodiacSign.name)) {// destinationView should start with lowercase, as it is a property
                        HStack {
                            Text(zodiacSign.Symbol)
                            Text(zodiacSign.name)
                        }
                    }
                }
            }
}
struct ZodiacSign: Identifiable {
    let id = UUID()
    var name: String
    var Symbol: String
    var DestinationView: View
}

var starSigns = [
    ZodiacSign(name: "Aries", Symbol: "♈︎", DestinationView: AriesView()),
    ZodiacSign(name: "Taurus", Symbol: "♉︎", DestinationView: TaurusView()),
    ZodiacSign(name: "Gemini", Symbol: "♊︎", DestinationView: GeminiView()),
    ZodiacSign(name: "Cancer", Symbol: "♋︎", DestinationView: CancerView()),
    ZodiacSign(name: "Leo", Symbol: "♌︎", DestinationView: LeoView()),
    ZodiacSign(name: "Virgo", Symbol: "♍︎", DestinationView: VirgoView()),
    ZodiacSign(name: "Libra", Symbol: "♎︎", DestinationView: LibraView()),
    ZodiacSign(name: "Scorpio", Symbol: "♏︎", DestinationView: ScorpioView()),
    ZodiacSign(name: "Sagittarius", Symbol: "♐︎", DestinationView: SagittariusView()),
    ZodiacSign(name: "Capricorn", Symbol: "♑︎", DestinationView: CapricornView()),
    ZodiacSign(name: "Aquarius", Symbol: "♒︎", DestinationView: AquariusView()),
    ZodiacSign(name: "Pisces", Symbol: "♓︎", DestinationView: PiscesView())
]

struct ContentView: View {
    var body: some View {
        VStack {
            List {
                ForEach(starSigns) {ZodiacSign in
                    NavigationLink(destination: ZodiacSign.DestinationView) {
                        Text(ZodiacSign.Symbol)
                        Text(ZodiacSign.name)
                    }
                }
            }
        }
    }
}

struct AriesView: View {
    var body: some View {
        VStack {
            
        }
    }
}

struct TaurusView: View {
    var body: some View {
        VStack {
            
        }
    }
}

struct GeminiView: View {
    var body: some View {
        VStack {
            
        }
    }
}

struct CancerView: View {
    var body: some View {
        VStack {
            
        }
    }
}

struct LeoView: View {
    var body: some View {
        VStack {
            
        }
    }
}

struct VirgoView: View {
    var body: some View {
        VStack {
            
        }
    }
}

struct LibraView: View {
    var body: some View {
        VStack {
            
        }
    }
}

struct ScorpioView: View {
    var body: some View {
        VStack {
            
        }
    }
}

struct SagittariusView: View {
    var body: some View {
        VStack {
            
        }
    }
}

struct CapricornView: View {
    var body: some View {
        VStack {
            
        }
    }
}

struct AquariusView: View {
    var body: some View {
        VStack {
            
        }
    }
}

struct PiscesView: View {
    var body: some View {
        VStack {
            
        }
    }
}

This is the full code, line 5 is where I was referring to earlier, I would like to add the destination in each one, please could you explain how I would do this.

Accepted Answer

I would do it this way with ViewBuilder:

struct ZodiacSign: Identifiable {
    let id = UUID()
    var name: String
    var symbol: String      // as per Swift conventions, should start with lowercase
    // Replaced by ViewBuilder  var DestinationView: View
}

@ViewBuilder func zodiacDestination(name: String) -> some View {
    switch name {
        case "Aries"    : AriesView()
        case "Taurus"   : TaurusView()
        case "Gemini"   : GeminiView()
        case "Cancer"   : CancerView()
        case "Leo"      : LeoView()
        case "Virgo"    : VirgoView()
        case "Libra"    : LibraView()
        case "Scorpio"  : ScorpioView()
        case "Sagittarius": SagittariusView()
        case "Capricorn": CapricornView()
        case "Aquarius" : AquariusView()
        case "Pisces"   : PiscesView()
        default: EmptyView()
      }
  }

struct ContentView: View {

    @State var starSigns = [    // Need to be a State var
        ZodiacSign(name: "Aries", symbol: "♈︎"),  // DestinationView: AriesView()),
        ZodiacSign(name: "Taurus", symbol: "♉︎"), // DestinationView: TaurusView()),
        ZodiacSign(name: "Gemini", symbol: "♊︎"), // DestinationView: GeminiView()),
        ZodiacSign(name: "Cancer", symbol: "♋︎"), // DestinationView: CancerView()),
        ZodiacSign(name: "Leo", symbol: "♌︎"), // DestinationView: LeoView()),
        ZodiacSign(name: "Virgo", symbol: "♍︎"), // DestinationView: VirgoView()),
        ZodiacSign(name: "Libra", symbol: "♎︎"), // DestinationView: LibraView()),
        ZodiacSign(name: "Scorpio", symbol: "♏︎"), // DestinationView: ScorpioView()),
        ZodiacSign(name: "Sagittarius", symbol: "♐︎"), // DestinationView: SagittariusView()),
        ZodiacSign(name: "Capricorn", symbol: "♑︎"), // DestinationView: CapricornView()),
        ZodiacSign(name: "Aquarius", symbol: "♒︎"), // DestinationView: AquariusView()),
        ZodiacSign(name: "Pisces", symbol: "♓︎") // DestinationView: PiscesView())
    ]

    var body: some View {
        // VStack {
        NavigationView { // You have to put in a NavigationView
            List {
                ForEach(starSigns, id: \.id) {zodiacSign in   // should start with lowercase
                    NavigationLink(destination: zodiacDestination(name: zodiacSign.name)) {
                        Text(zodiacSign.symbol)
                        Text(zodiacSign.name)
                    }
                }
            }
        }
    }
}

struct AriesView: View {
    var body: some View {
        VStack {
            Text("♈︎ Aries is a constellation…")
        }
    }
}

struct TaurusView: View {
    var body: some View {
        VStack {
            Text("♉︎ Taurus is a constellation…")
        }
    }
}

struct GeminiView: View {
    var body: some View {
        VStack {
            Text("♊︎ Gemini is a constellation…")
        }
    }
}

To add to @Claude31 point, since you have a custom data type ZodiacSign, you could use value based navigation where you associate a view with a kind of data, and then present a value of that data type from a navigation link using the navigationDestination(for:destination:) modifier.

I would recommend you have a look at Migrating to new navigation types article, it contains various examples of programmatic navigation.

Thank you for the help, it works now!!! :D

Variable for DestinationView
 
 
Q