0

I am new to Swift for a macOS app and I don't understand how to make NavigationLink work to go to a new view. For example, I made a Sign In view and want to make a button that leads to a Sign Up view. Would I use NavigationLink so that the app can change to a different view? Is there an alternative to NavigationLinK? I tried to use NavigationLink, but the button was greyed out and I could not click it.

enter image description here

Here is what I tried:

HStack{
             Text("Don't have an account yet?")
                 .foregroundColor(.gray)
                        
      }
      .padding(.top, 10)
      NavigationLink("Create Account", destination:SignUpView())
                    
  }

Here is my SignUp view:

struct SignUpView: View {
    var screen=NSScreen.main?.visibleFrame

    //email and password fields
    @State var email=""
    @State var password=""
    @State var keepLogged=false
    @EnvironmentObject var viewModel: AppViewModel
    
    //alert
    @State var alert = false
    var body: some View {
        HStack(spacing:0){
            VStack{
                Spacer(minLength:0)
                Image("logo")
                    .resizable()
                    .aspectRatio(contentMode: .fit)
                    .frame(width:100, height:100)
                Text("The Organized Cook")
                    .font(.largeTitle)
                    .fontWeight(.heavy)
                    .foregroundColor(.black)
                    .padding(.vertical, 10)
                
                Group{
                    //Email
                    TextField("Email", text:$email)
                        .textFieldStyle(PlainTextFieldStyle())
                        .padding(.vertical, 10)
                        .padding(.horizontal)
                    //Borders
                        .background(RoundedRectangle(cornerRadius:2).stroke(Color.gray.opacity(0.7), lineWidth:1))
                    //password
                    
                    SecureField("Password", text:$password)
                        .textFieldStyle(PlainTextFieldStyle())
                        .padding(.vertical,10)
                        .padding(.horizontal)
                    //Borders
                        .background(RoundedRectangle(cornerRadius:2).stroke(Color.gray.opacity(0.7), lineWidth:1))
                        .padding(.vertical)
                    //keep login and forget password
                    HStack{
                        Toggle("", isOn: $keepLogged)
                            .labelsHidden()
                            .toggleStyle(CheckboxToggleStyle())
                        Text("Stay Logged In")
                            .foregroundColor(.black)
                        Spacer(minLength:0)
                        
                        Button(action: {}, label: {
                            Text("Forget Password")
                                .foregroundColor(.black)
                                .underline(true,color:Color.black)
                        })
                            .buttonStyle(PlainButtonStyle())
                    }
                    // log in
                    Button(action: {alert.toggle()
                        
                        guard !email.isEmpty, !password.isEmpty else{
                            return
                        }
                        viewModel.signUp(email: email, password: password)
                 
                    }, label: {
                      
               
                        HStack{
                            
                            Spacer()
                            Text("Sign up")
                            
                            Spacer()
                            Image(systemName: "arrow.right")
                            
                        }
                        .foregroundColor(.white)
                        .padding(.vertical, 10)
                        .padding(.horizontal)
                        .background(Color("test"))
                        .cornerRadius(2)
                    })
                        .buttonStyle(PlainButtonStyle())
                        .padding(.top)
                    
                    //sign up
                    HStack{
                        Text("Already have an account?")
                            .foregroundColor(.gray)
                        Button(action: {}, label: {
                            Text("Sign in")
                                .foregroundColor(.blue)
                                .underline(true,color:Color.black)
                        })
                            .buttonStyle(PlainButtonStyle())
                    }
                    .padding(.top, 10)
                }
                
                Spacer(minLength:0)
            }
        
   
            //white half of signup
            .padding(.horizontal, 50)
            .frame(maxWidth: .infinity, maxHeight: .infinity)
            .background(Color.white)
            //always light mode
            .preferredColorScheme(.light)
            .alert(isPresented: $alert, content: {
                Alert(title: Text("Message"), message: Text("Logged Successfully"), dismissButton: .destructive(Text("Ok")))
            })
            VStack{
                Spacer()
          
              
            }
            .frame(width: (screen!.width / 1.8) / 2)
            .background(Color("test"))
        }
        .ignoresSafeArea(.all, edges: .all)
        .frame(width: screen!.width / 1.8, height: screen!.height - 100)
    }
}

jari85
  • 71
  • 5
  • Does this answer your question? [Swift: Why does the iPad/Mac app version look weird](https://stackoverflow.com/questions/70482156/swift-why-does-the-ipad-mac-app-version-look-weird) – lorem ipsum Nov 17 '22 at 13:19

1 Answers1

0

A NavigationLink only works inside a NavigationView.

Somewhere in the view hierarchy above the navigation link make sure you have a NavigationView.

An example of this:

NavigationView{
...

  HStack{
             Text("Don't have an account yet?")
                 .foregroundColor(.gray)
                        
        }
        .padding(.top, 10)
  NavigationLink("Create Account", destination:SignUpView())
                    
  }
...
}
Mozahler
  • 4,958
  • 6
  • 36
  • 56
  • Is there an alternative to NavigationLink? I just want to go from one view to another, and would prefer not to use NavigationView. I feel NavigationView isn't the best option for a sign in screen. – jari85 Nov 17 '22 at 13:38
  • You could use a .sheet - it pops up from the bottom. You could also just have if $someToggleValue { show login screen } else { show current code - minus the link }. Just do someToggleValue.toggle() when you want the login screen to show. The toggle back when you're done. – Mozahler Nov 17 '22 at 13:39
  • I don't think a sheet would help either. I just want to press a button and go to a new view. For example, I would also use the concept when a person logs in to go to the "home" view. They press "log in" and the screen shifts to the home view. How might I accomplish this? – jari85 Nov 17 '22 at 13:46
  • My third suggestion (using the @State variable and toggling it) does exactly that. Try it out. You can have the target view defined separately( in a different file even). if $showLogin { TheLoginView($showLogin) } else { existing code } – Mozahler Nov 17 '22 at 13:50
  • I don't want a person to have to toggle to log in. How do most macOS apps do it? NavigationView doesn't work because it messes with the look of the app and doesn't properly go to a new view. – jari85 Nov 18 '22 at 08:52
  • 1
    They don't toggle anything directly. That's something you do in response to them tapping the login button. you can set $shouldLogin = true in the view at initialization and start there. Browse the swift apps in GitHub for ideas! There's many different ways to do it. – Mozahler Nov 18 '22 at 14:24