I have a form where if a user doesn't provide adaquate credentials to the email and password fields a prompt will show up. Issue is the prompts are creating an extra row where they are present (under email and password).
I tried hiding the separators, but then I'm left with a huge gap of space. Is there a way I can remove the list rows and just have every element shift down when the text is present like so? The password prompt isn't as noticeable as there still is space between the button and row.
NavigationView{
ZStack{
Form{
Section(){
TextField("FirstName", text: $userInformation.firstname)
TextField("LastName", text: $userInformation.lastname)
TextField("Email", text: $userInformation.email)
Text(userInformation.emailPrompt)
.font(.caption).italic().foregroundColor(.red)
.listStyle(.inset)
SecureField("Passsword", text: $userInformation.password
).autocapitalization(.none)
Text(userInformation.passwordPrompt)
.font(.caption).italic().foregroundColor(.red)
}
.listRowBackground(Color.clear)
.padding()
.navigationBarTitle(Text("Lets Get Started"))
.navigationBarTitleDisplayMode(.automatic)
.font(.system(size:18))
.listStyle(GroupedListStyle())
}
NavigationLink(destination: JournalEntryMain() .navigationBarHidden(true)){
Text("Sign Up")
.frame(width: 250, height: 20)
.foregroundColor(.white)
.padding()
// .multilineTextAlignment(.leading)
.background(LinearGradient(gradient: Gradient(colors: [.orange, .pink]), startPoint: .leading, endPoint: .bottom))
.font(.title3)
.background(.clear)
.cornerRadius(5)
.offset(y:30)
.opacity(userInformation.isSignUpComplete ? 1 : 0.5)
}
class FormViewModel: ObservableObject {
@Published var firstname = ""
@Published var lastname = ""
@Published var email = ""
@Published var gender = ""
@Published var password = ""
func isPasswordValid() -> Bool {
let passwordTest = NSPredicate(format: "SELF MATCHES%@", "^(?=.*\\d)(?=.*[a-z])(?=.*[A-Z]).{8,15}$")
return passwordTest.evaluate(with: password)
}
func isEmailValid() -> Bool {
let emailTest = NSPredicate(format: "SELF MATCHES%@", "^([a-zA-Z0-9_\\-\\.] )@((\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.)|(([a-zA-Z0-9\\-] \\.) ))([a-zA-Z]{2,4}|[0-9]{1,3})(\\]?)$")
return emailTest.evaluate(with: email)
}
//email and password prompts if incomplete or incorrect
var emailPrompt: String {
if isEmailValid() || email == "" {
return ""
} else {
return "*Please enter a valid email address"
}
}
var passwordPrompt: String {
if isPasswordValid() || password == ""{
return ""
} else {
return "*Password must be 8-15 letters, with atleast one uppercase and one number"
}
}
var isSignUpComplete: Bool {
if !isPasswordValid() || !isEmailValid() || firstname == "" || lastname == "" {
return false
}
return true
}
}
CodePudding user response:
The simplest approach would be a conditional:
if userInformation.passwordPrompt != "" {
Text(userInformation.passwordPrompt)
.font(.caption).italic().foregroundColor(.red)
}
This will conditionally remove it from the view. You can also animate the appearance/disappearance.