I can send it with pleasure, by mail because code is very dense, but I think I found what was wrong:
Apple says about @FocusState:
A property wrapper type that can read and write a value that SwiftUI updates as the placement of focus within the scene changes.
to use this FocusState property, I used an enum declaration which was contained in the main view. But if I want to make a TextfieldWithError view, which use this enum, I have to declare this enum alone, not in my main View:
enum LoginFocusable: Hashable {
case email
case pwd
case none
var string: String {
switch self {
case .email: return "email"
case .pwd: return "pwd"
default: return ""
}
}
var nextToVerif: LoginFocusable {
switch self {
case .email: return .pwd
case .pwd: return .email
default: return .none
}
}
}
that's the first point
So, in TextfieldInError, I can have the declaration:
struct TextFieldWithError: View {
var label: String
@Binding var text: String
@Binding var textError: String
@FocusState.Binding var focus: LoginFocusable?
}
But t's not enough, because I will need to use the .focused modifier in TextFieldWithError so, I have to declare another property in TextFieldWithError: focusId of type LoginFocusable, so I will be able to user the .focused modifier
So my code will be
struct TextFieldWithError: View {
var label: String
@Binding var text: String
@Binding var textError: String
var focusId: LoginFocusable?
@FocusState.Binding var focus: LoginFocusable?
var body: some View {
TextField(label, text: $text)
.modifier(TextFieldStyle())
.focused($focus, equals: focusId)
Text(textError)
.foregroundColor(.red)
.frame(height: textError == "" ? 0 : 20)
}
}
Now, in the main view, I can declare:
TextFieldWithError(label: "Email", text: $email, textError: $emailError, focusId: .email, focus: $checkoutInFocus)
Of course, the logic of focus handle has to be written in this main View