'Type '() -> ()' cannot conform to 'View'
I'm trying to put an if statement inside a NavigationLink using Xcode.
This is my code:
NavigationLink(destination: {
if location.name == "Firm of the Future" {
StartView()
} else {
Finish()
}
}, label: {
Text("Leer meer")
.font(.headline)
.frame(width: 125, height: 35)
})
With this code I'm getting the error:
Type '() -> ()' cannot conform to 'View'
But when I use this code:
NavigationLink(destination: {
if location.name == "Firm of the Future" {
Text("Screen 1")
} else {
Text("Screen 2")
}
}, label: {
Text("Leer meer")
.font(.headline)
.frame(width: 125, height: 35)
})
it works.
What am I doing wrong in the first code?
This is the code for the views: I'm using multiple bindings.
import SwiftUI
struct StartView: View {
@State var Q1: String
@State var Q2: String
@State var Q3: String
@State var Q4: String
@State var Q5: String
@State var Q6: String
@State var Q7: String
@State var Q8: String
@State var theAnswer1: String
@State var theAnswer2: String
@State var theAnswer3: String
@State var theAnswer4: String
@State var theAnswer5: String
@State var theAnswer6: String
@State var theAnswer7: String
@State var theAnswer8: String
@State var AnsBool1: Bool
@State var AnsBool2: Bool
@State var AnsBool3: Bool
@State var AnsBool4: Bool
@State var AnsBool5: Bool
@State var AnsBool6: Bool
@State var AnsBool7: Bool
@State var AnsBool8: Bool
var body: some View {
ZStack{
Image("WolvenBack")
.resizable()
.aspectRatio(contentMode: .fill)
.ignoresSafeArea()
Image("FEClogokleur")
.resizable()
.aspectRatio(contentMode: .fill)
.frame(width: 70, height: 70, alignment: .leading)
.position(x: 370, y: -70)
VStack{
Spacer()
Text("De klim naar")
.font(.largeTitle)
.foregroundColor(.white)
.shadow(color: .black, radius: 10, x: 10, y: 10)
Text("het Wolvennest")
.font(.largeTitle)
.foregroundColor(.white)
.shadow(color: .black, radius: 10, x: 10, y: 10)
Spacer()
NavigationLink(
destination: FietsStap1(Q1: $Q1, Q2: Q2, Q3: Q3, Q4: Q4, Q5: Q5, Q6: Q6, Q7: Q7, Q8: Q8, theAnswer1: $theAnswer1, theAnswer2: $theAnswer2, theAnswer3: $theAnswer3, theAnswer4: $theAnswer4, theAnswer5: $theAnswer5, theAnswer6: $theAnswer6, theAnswer7: $theAnswer7, theAnswer8: $theAnswer8, AnsBool1: $AnsBool1, AnsBool2: $AnsBool2, AnsBool3: $AnsBool3,AnsBool4: $AnsBool4, AnsBool5: $AnsBool5, AnsBool6: $AnsBool6,AnsBool7: $AnsBool7,AnsBool8: $AnsBool8),
label: {
Circle()
.fill(Color(red: 0.739, green: 0.818, blue: 0.022))
.frame(width: 120, height: 200, alignment: .bottom)
.padding(10)
.shadow(color: .black, radius: 10, x: 10, y: 10)
.overlay(
Text("Start")
.font(.largeTitle)
.foregroundColor(.black)
)}
)}
}
}
}
struct StartView_Previews: PreviewProvider {
@State static var Q1 = String().self
@State static var Q2 = String().self
@State static var Q3 = String().self
@State static var Q4 = String().self
@State static var Q5 = String().self
@State static var Q6 = String().self
@State static var Q7 = String().self
@State static var Q8 = String().self
@State static var theAnswer1 = String().self
@State static var theAnswer2 = String().self
@State static var theAnswer3 = String().self
@State static var theAnswer4 = String().self
@State static var theAnswer5 = String().self
@State static var theAnswer6 = String().self
@State static var theAnswer7 = String().self
@State static var theAnswer8 = String().self
@State static var AnsBool1 = Bool().self
@State static var AnsBool2 = Bool().self
@State static var AnsBool3 = Bool().self
@State static var AnsBool4 = Bool().self
@State static var AnsBool5 = Bool().self
@State static var AnsBool6 = Bool().self
@State static var AnsBool7 = Bool().self
@State static var AnsBool8 = Bool().self
static var previews: some View {
Group {
NavigationView {
StartView(Q1: Q1, Q2: Q2, Q3: Q3, Q4: Q4, Q5: Q5, Q6: Q6, Q7: Q7, Q8: Q8, theAnswer1: theAnswer1, theAnswer2: theAnswer2, theAnswer3: theAnswer3, theAnswer4: theAnswer4, theAnswer5: theAnswer5, theAnswer6: theAnswer6, theAnswer7: theAnswer7, theAnswer8: theAnswer8, AnsBool1: AnsBool1, AnsBool2:AnsBool2,AnsBool3: AnsBool3,AnsBool4: AnsBool4, AnsBool5: AnsBool5, AnsBool6: AnsBool6,AnsBool7: AnsBool7,AnsBool8: AnsBool8)
}
}
}
}
Finish View
import SwiftUI
struct Finish: View {
var body: some View {
ZStack {
Image("WolvenBack")
.resizable()
.aspectRatio(contentMode: .fill)
.ignoresSafeArea()
.navigationBarHidden(true)
Image("FEClogokleur")
.resizable()
.aspectRatio(contentMode: .fill)
.frame(width: 70, height: 70, alignment: .leading)
.position(x: 410, y: 40)
VStack{
Text("")
.padding(.bottom, 140)
ScrollView {
Text("Gefeliciteerd! Je hebt de puzzel opgelost.")
.frame(width: 300)
.foregroundColor(.white)
.font(.title)
.padding(.vertical,10)
.shadow(color: .black, radius: 10, x: 10, y: 10)
Text("Je bent nu expert op het gebied van de wolf!")
.frame(width: 300)
.foregroundColor(.white)
.font(.title)
.padding(.bottom, 50)
.shadow(color: .black, radius: 10, x: 10, y: 10)
Image("Trophy")
.resizable()
.frame(width: 300, height: 250, alignment: .center)
.shadow(color: .black, radius: 10, x: 10, y: 10)
}
}
}
}
}
struct Finish_Previews: PreviewProvider {
static var previews: some View {
Finish()
}
}
Solution 1:[1]
In your first example, your if statement can return either a StartView or a Finish. The trouble is that the destination: block has to return a concrete type - that is, always the same type of object that conforms to the View protocol. The second example works because whatever path through the if statement is taken, it will always return a Text view.
The good news is that you can wrap your if statement in a Group – a semantically neutral view that can contain multiple types of view, but will wrap them in such a way that destination always receives the same type of view:
NavigationLink(destination: {
Group {
if location.name == "Firm of the Future" {
StartView()
} else {
Finish()
}
}
}, label: {
Text("Leer meer")
.font(.headline)
.frame(width: 125, height: 35)
})
Solution 2:[2]
The problem is that you are not initialising all the @State variables of StartView(). You have 24 variables not initialised and no init().
XCode always has a hard time processing Views when they are just a little bit complicated, so you see an error in the NavigationLink because it can't process its contents.
Either you put a default value on each variable, like @State var Q1: String = "", or you create an init() { }, but then you'll have to provide the values in your call to StartView(Q1: "Hello, Q2: "World", ...).
Solution 3:[3]
Assuming that Finish is a view... You need to provide a single view for navigation link instead of closure, so most simple fix is to use Group, like
NavigationLink(destination: Group { // << here !!
if location.name == "Firm of the Future" {
StartView()
} else {
Finish()
}
}, label: {
Text("Leer meer")
.font(.headline)
.frame(width: 125, height: 35)
})
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | ScottM |
| Solution 2 | HunterLion |
| Solution 3 | Asperi |
