skip to Main Content

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


  1. Ternary operations are not good with SwiftUI Views you can try a switch

    Group{
        switch loggedIn {
        case true:
            DashboardView() 
        case false:
            SignInView()
         }
    }
    
    Login or Signup to reply.
  2. 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.

    var body: some View {
        if loggedIn {
            DashboardView()
        } else {
                SignInView()
        }
    }
    
    Login or Signup to reply.
  3. 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.

    NavigationLink(
        destination: loggedIn ? AnyView(DashboardView()) : AnyView(SignInView()),
        isActive: $loggedIn,
        label: {
            Text("Sign In")
        }
    )
    

    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.

    @ViewBuilder
    private var destinationView: some View {
        if loggedIn {
            DashboardView()
        } else {
            SignInView()
        }
    }
    

    And use destinationView in the NavigationLink.

    NavigationLink(
        destination: destinationView,
        isActive: $loggedIn,
        label: {
            Text("Sign In")
        }
    )
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search