Reputation: 1
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
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
:
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.Image("SignIn")
.resizable()
.scaledToFit()
// .padding(EdgeInsets(top: 100, leading: 0, bottom: 10, trailing: 0))
.padding(.top, 100)
Image("S")
.resizable()
.scaledToFit()
.frame(height: 50)
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)
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:
Upvotes: 1