Implemented focus and handling of the return key presses in the LoginForm view apart from overall UI improvements.

This commit is contained in:
Javier Cicchelli 2022-12-02 18:16:51 +01:00
parent 48bb53afcc
commit a3a44a90b0

View File

@ -10,12 +10,20 @@ import SwiftUI
struct LoginForm: View { struct LoginForm: View {
// MARK: States
@FocusState private var focusedField: Field?
// MARK: Bindings // MARK: Bindings
@Binding var username: String @Binding var username: String
@Binding var password: String @Binding var password: String
@Binding var errorMessage: String? @Binding var errorMessage: String?
// MARK: Properties
let onReturn: () -> Void
// MARK: Body // MARK: Body
var body: some View { var body: some View {
@ -23,25 +31,33 @@ struct LoginForm: View {
alignment: .leading, alignment: .leading,
spacing: 16 spacing: 16
) { ) {
TextField( TextField("Username", text: $username) { isBeginEditing in
"Username", guard isBeginEditing, errorMessage != nil else { return }
text: $username
) errorMessage = nil
.textContentType(.username) }
.autocapitalization(.none) .textContentType(.username)
.disableAutocorrection(true) .lineLimit(1)
.keyboardType(.default) .autocapitalization(.none)
.disableAutocorrection(true)
.keyboardType(.default)
.focused($focusedField, equals: .username)
.onSubmit {
onUsernameReturnPressed()
}
Divider() Divider()
SecureField( SecureField("Password", text: $password)
"Password", .textContentType(.password)
text: $password .lineLimit(1)
) .autocapitalization(.none)
.textContentType(.password) .disableAutocorrection(true)
.autocapitalization(.none) .keyboardType(.default)
.disableAutocorrection(true) .focused($focusedField, equals: .password)
.keyboardType(.default) .onSubmit {
onPasswordReturnPressed()
}
if let errorMessage { if let errorMessage {
Divider() Divider()
@ -53,7 +69,7 @@ struct LoginForm: View {
} }
.frame(maxWidth: .infinity, alignment: .leading) .frame(maxWidth: .infinity, alignment: .leading)
.padding(16) .padding(16)
.background(Color.white) .background(Color.primary.colorInvert())
.cornerRadius(8) .cornerRadius(8)
.onAppear { .onAppear {
setClearButtonIfNeeded() setClearButtonIfNeeded()
@ -69,6 +85,41 @@ private extension LoginForm {
UITextField.appearance().clearButtonMode = .whileEditing UITextField.appearance().clearButtonMode = .whileEditing
} }
func onUsernameReturnPressed() {
guard !username.isEmpty else {
focusedField = .username
return
}
if password.isEmpty {
focusedField = .password
} else {
onReturn()
}
}
func onPasswordReturnPressed() {
guard !password.isEmpty else {
focusedField = .password
return
}
if username.isEmpty {
focusedField = .username
} else {
onReturn()
}
}
}
// MARK: - Enumerations
private extension LoginForm {
enum Field: Hashable {
case username
case password
}
} }
// MARK: - Previews // MARK: - Previews
@ -78,14 +129,16 @@ struct LoginForm_Previews: PreviewProvider {
LoginForm( LoginForm(
username: .constant("Some username"), username: .constant("Some username"),
password: .constant("Some Password"), password: .constant("Some Password"),
errorMessage: .constant(nil) errorMessage: .constant(nil),
onReturn: {}
) )
.previewDisplayName("Login form with no error message") .previewDisplayName("Login form with no error message")
LoginForm( LoginForm(
username: .constant("Some username"), username: .constant("Some username"),
password: .constant("Some Password"), password: .constant("Some Password"),
errorMessage: .constant("Some error goes in here...") errorMessage: .constant("Some error goes in here..."),
onReturn: {}
) )
.previewDisplayName("Login form with some error message") .previewDisplayName("Login form with some error message")
} }