Lakshay Gupta
Lakshay Gupta

Reputation: 1

Body not in proper position while navigating in SwiftUI

Recently tried using SwiftUI . While working with Navigation the UI keeps breaking when going from one screen to another. I am using NavigationStack and NavigationLink while navigating from one screen to another.

Sreenshots of original login screen / login screen after navigating from GetStarted screen:

import SwiftUI

struct GetStartedScreen: View {
    var body: some View {
        NavigationStack {
            GeometryReader { geometry in
                VStack {
                    HStack {
                        Text("Your Thoughts")
                            .font(.system(size: 30))
                        
                        Text("Cleaner")
                            .foregroundColor(Color(red: 0.0, green: 0.545, blue: 0.545))
                            .font(.system(size: 30))
                            .bold()
                    }
                    .padding(.top, 40)
                    .frame(maxWidth: .infinity, alignment: .center)
                    
                    Text("Let the music take control!")
                        .font(.system(size: 20))
                        .padding(.top, 16)
                        .frame(maxWidth: .infinity, alignment: .center)
                    
                    Image("Yoga")
                        .resizable()
                        .aspectRatio(contentMode: .fit)
                        .frame(width: geometry.size.width * 0.90, height: geometry.size.height * 0.66)
                    
                    Spacer()
                    
                    NavigationLink(destination: LoginScreen()) {
                        Text("Get Started →")
                            .frame(width: geometry.size.width * 0.70)
                            .font(.system(size: 20))
                            .bold()
                            .foregroundColor(.white)
                            .padding()
                            .background(Color(red: 0.0, green: 0.545, blue: 0.545))
                            .cornerRadius(10)
                    }
                    .padding(.bottom , 40)
                }
            }
        }
    }
}
struct ForgotUsername: View {
    @State private var username: String = ""
    @State private var phoneNumber: String = ""
    @State private var email: String = ""
    @State private var isPhoneNumber: Bool = true
    @FocusState private var isUsernameFieldFocused: Bool
    @FocusState private var isPhonenumberFieldFocused: Bool
    @FocusState private var isEmailFieldFocused: Bool
    
    var body: some View {
        GeometryReader { geometry in
            NavigationStack {
                VStack {
                    Image("SignIn")
                        .padding(EdgeInsets(top: 100, leading: 0, bottom: 10, trailing: 0))
                    
                    VStack {
                        Text("Login")
                            .font(.system(size: 28))
                            .bold()
                            .padding(EdgeInsets(top: 16, leading: 0, bottom: 4, trailing: 0))
                        
                        HStack {
                            Text("Welcome To")
                                .font(.system(size: 26))
                            
                            Text("Soundly")
                                .foregroundColor(Color(red: 0.0, green: 0.545, blue: 0.545))
                                .font(.system(size: 26))
                                .bold()
                        }
                        
                        Text("Enter your registered \n \(isPhoneNumber ? "Phone Number" : "Email")")
                            .font(.system(size: 22))
                            .multilineTextAlignment(.center)
                            .padding(EdgeInsets(top: 4, leading: 16, bottom: 0, trailing: 16))
                        
                        VStack(alignment: .leading) {
                            HStack(alignment: .center) {
                                Text(isPhoneNumber ? "Phone Number" : "Email")
                                    .font(.system(size: 14))
                                Spacer()
                                Button(action: {
                                    isPhoneNumber.toggle()
                                }) {
                                    Text("via \(isPhoneNumber ? "Email" : "Phone")")
                                        .foregroundColor(.teal)
                                        .bold()
                                        .font(.system(size: 10))
                                }
                            }
                            
                            if isPhoneNumber {
                                TextField("Enter your phone number", text: $phoneNumber)
                                    .padding()
                                    .background(Color.clear)
                                    .overlay(
                                        RoundedRectangle(cornerRadius: 10)
                                            .stroke(!isPhonenumberFieldFocused ? Color.gray : Color.black, lineWidth: 1)
                                    )
                                    .cornerRadius(10)
                                    .padding(.bottom, 10)
                                    .focused($isPhonenumberFieldFocused)
                            } else {
                                TextField("Enter your email", text: $email)
                                    .padding()
                                    .background(Color.clear)
                                    .overlay(
                                        RoundedRectangle(cornerRadius: 10)
                                            .stroke(!isEmailFieldFocused ? Color.gray : Color.black, lineWidth: 1)
                                    )
                                    .cornerRadius(10)
                                    .padding(.bottom, 10)
                                    .focused($isEmailFieldFocused)
                            }
                        }
                        .padding(EdgeInsets(top: 10, leading: 16, bottom: 0, trailing: 16))
                  
                        NavigationLink(destination: OTPScreen(isPhoneNumber: isPhoneNumber, contactInfo: isPhoneNumber ? phoneNumber : email)) {
                            Text("Continue")
                                .frame(width: geometry.size.width * 0.85)
                                .font(.system(size: 20))
                                .bold()
                                .foregroundColor(.white)
                                .padding()
                                .background(Color(red: 0.0, green: 0.545, blue: 0.545))
                                .cornerRadius(10)
                        }
                        
                        Spacer()
                    }
                    .frame(width: geometry.size.width, height: geometry.size.height * 0.62)
                    .background(Color(red: 213/255, green: 234/255, blue: 234/255, opacity: 1.0))
                    .cornerRadius(50)
                    .padding()
                    
                }
                .toolbar {
                    ToolbarItem(placement: .automatic) {
                        HStack {
                            Spacer()
                            Image("S")
                            Text("Soundly")
                                .font(.system(size: 28))
                            
                            Button {
                                // action
                            } label: {
                                Text("Login")
                                    .foregroundColor(Color(red: 0.0, green: 0.545, blue: 0.545))
                                    .bold()
                                    .font(.system(size: 20))
                            }
                            .padding(.leading, 40)
                        }
                    }
                }
            }
            .ignoresSafeArea(.keyboard)
        }
    }
}

Thanks for the Help !

Tried Video Tutorials but nothing worked

Upvotes: 0

Views: 51

Answers (1)

Benzy Neez
Benzy Neez

Reputation: 21730

In GetStartedScreen there is a NavigationLink that takes you to LoginScreen and this is probably the screenshot you are showing. However, you seem to have provided the code for ForgotUsername instead of LoginScreen.

Anyway, assuming that LoginScreen and ForgotUsername are similar, I would suggest these changes to ForgotUsername:

  • Remove the GeometryReader. You are using this to find the size of the screen. It might work better, if you let the components fit into the space available, instead of forcing a size on them.
  • Whenever you have an image, it is probably a good idea to scale it to fit into the space available. For example:
Image("SignIn")
    .resizable()
    .scaledToFit()
//    .padding(EdgeInsets(top: 100, leading: 0, bottom: 10, trailing: 0))
    .padding(.top, 100)
Image("S")
    .resizable()
    .scaledToFit()
    .frame(height: 50)
  • When you want to use the full width of the screen, set maxWidth: .infinity. If you want some space at the side, just add padding. BTW, .cornerRadius is deprecated, better to use .clipShape instead:
Text("Continue")
//    .frame(width: geometry.size.width * 0.85)
    .frame(maxWidth: .infinity)
    .font(.system(size: 20))
    .bold()
    .foregroundColor(.white)
    .padding()
    .background(Color(red: 0.0, green: 0.545, blue: 0.545))
    .clipShape(RoundedRectangle(cornerRadius: 10))
    .padding(.horizontal)
  • Likewise, you can use maxHeight: .infinity to use the full height, or a minHeight if you want to ensure that a panel is at least a certain height, adding padding where needed:
VStack {
    Text("Login")
    // ...
}
// .frame(width: geometry.size.width, height: geometry.size.height * 0.62)
.frame(maxWidth: .infinity, minHeight: 380)
.background(Color(red: 213/255, green: 234/255, blue: 234/255, opacity: 1.0))
.clipShape(RoundedRectangle(cornerRadius: 50))
.padding()
.padding(.bottom, 20)

Hopefully that gets you started and resolves the main issues of content not fitting properly. With just the changes above, ForgotUsername loooks like this:

Screenshot

Upvotes: 1

Related Questions