Result values in ‘? :’ expression have mismatching types ‘DashboardView’ and ‘SignInView’
i have login interface , when the fields are correctly filled it redirect me to the dashboardView .
this is my code :
VStack(spacing: 20) {
TextField("Email", text: $email)
.padding()
.background(Color(UIColor.secondarySystemBackground).opacity(0.5)) // Set opacity to 0.5
.cornerRadius(30)
.disableAutocorrection(true)
SecureField("Password", text: $password)
.padding()
.background(Color(UIColor.secondarySystemBackground).opacity(0.5)) // Set opacity to 0.5
.cornerRadius(30) }
.padding(.horizontal)
.padding(.bottom, 30)
Button(action: signIn) {
HStack {
Image(systemName: "key.fill")
.font(.headline)
.foregroundColor(.white)
Text("Sign In")
.font(.headline)
.foregroundColor(.white)
}
.frame(maxWidth: .infinity)
.padding()
.background(
ZStack {
Color.purple
if isLoading {
Color.white.opacity(0.4)
ProgressView()
.progressViewStyle(CircularProgressViewStyle(tint: .purple))
}
}
)
.cornerRadius(10)
.disabled(isLoading)
}
.cornerRadius(30)
.padding(.horizontal)
NavigationLink(
destination: loggedIn ? DashboardView() : SignInView(), // Change this line
isActive: $loggedIn,
label: {
Text("Sign In")
}
)
NavigationLink(
destination: ForgetPasswordView(),
label: {
Text("Forgot password?")
.font(.custom("arial", size: 20))
.fontWeight(.bold)
.foregroundColor(.white)
.padding()
.background(.clear)
.cornerRadius(10)
})
.alert(isPresented: $showAlert) {
Alert(title: Text("Error"), message: Text("Please enter your email and password"), dismissButton: .default(Text("OK")))
}
Text("Don't have an account?")
.font(.custom("arial", size: 20))
.fontWeight(.bold)
.padding(.bottom, 30)
.foregroundColor(.white)
.padding(.horizontal)
HStack(spacing: 10) {
Button(action: signInWithApple) {
Image("apple-icon")
.resizable()
.frame(width: 20, height: 20)
.foregroundColor(.white)
}
.frame(width: 50, height: 50)
.background(Color.black)
.cornerRadius(25)
Button(action: signInWithGoogle) {
Image("google-icon")
.resizable()
.frame(width: 20, height: 20)
.foregroundColor(.white)
}
.frame(width: 50, height: 50)
.background(Color.red)
.cornerRadius(25)
}
.padding(.horizontal)
Spacer()
}
}
}
func signIn() {
guard !email.isEmpty && !password.isEmpty else {
showAlert = true
return
}
loginViewModel.loginUser(username: email, password: password) { loginModel in
if let loginModel = loginModel {
loggedIn = true
} else {
// Handle failed login here
}
}
}
3
Answers
Ternary operations are not good with SwiftUI Views you can try a
switch
You are returning two different types from the evaluation / ternary operator and NavigationLink only accepts a single confirmed view type to compile. To solve this you should create a new view which receives loggedIn as a parameter. NavigationLink then only has the one view type that it requires. In new subview it links to you can run the if statement to determine which view to display.
NavigationLink
expects to know the type of view it should navigate to. When you conditionally change the destination views,NavigationView
would not be aware of the destination’s type and hence the error.Try enclosing the views within
AnyView
.This way the destination is always of type
AnyView
irrespective of the loggedIn flag.EDIT:
Below is an implementation based on the article shared by @Hongtron.
You can use
@ViewBuilder
annotation to first create the destination view.And use
destinationView
in theNavigationLink
.