#swiftui
#swiftui
Вопрос:
У меня есть пользовательское текстовое поле:
struct InputField: View {
var inputText: Binding<String>
var title: String
var placeholder: String
@State var hasError = false
var body: some View {
VStack(spacing: 5.0) {
HStack {
Text(title)
.font(.subheadline)
.fontWeight(.semibold)
Spacer()
}
TextField(placeholder, text: inputText).frame(height: 50).background(Color.white)
.cornerRadius(5.0)
.border(hasError ? Color.red : Color.clear, width: 1)
}
}
}
моя модель представления:
class LoginViewModel: ObservableObject {
@Published var username = "" {
didSet {
print("username is: (username)")
}
}
func checkUsernameisValid() -> Bool {
return username.count < 6
}
}
и мой окончательный вид входа в систему:
@ObservedObject var loginViewModel = LoginViewModel()
var inputFields: some View {
VStack {
InputField(inputText: $loginViewModel.username, title: "Username:", placeholder: " Enter your username", hasError: $loginViewModel.checkUsernameisValid())
InputField(inputText: $loginViewModel.password, title: "Password:", placeholder: " Enter your password", hasError: $loginViewModel.checkUsernameisValid())
}
}
Теперь это жалуется на hasError:$loginViewModel.checkUsernameisValid()
то, что я не могу привязать функцию к переменной состояния hasError
.
Как я могу заставить это работать, продолжая использовать функцию checkUsernameisValid()
для обновления моего пользовательского представления текстового поля?
Один из способов решить эту проблему — использовать другую опубликованную переменную в моей модели представления
@Published var validUsername = false
func checkUsernameisValid() {
validUsername = username.count < 6
}
и продолжайте вызывать эту функцию в didSet моего имени пользователя var
@Published var username = "" {
didSet {
print("username is: (username)")
checkUsernameisValid()
}
}
наконец, используйте новую опубликованную переменную для привязки ошибки:
hasError: $loginViewModel.validUsername
Мой вопрос в том, это единственный способ? т.е. Использовать @published var для привязки, и я не могу использовать автономные функции напрямую, чтобы делать то же самое, вместо того, чтобы использовать все больше и больше переменных @Published ?
Ответ №1:
Вам не нужна привязка для ошибки. InputField
Будет обновляться inputText
, поэтому вам просто нужно обычное свойство, например
struct InputField: View {
var inputText: Binding<String>
var title: String
var placeholder: String
var hasError = false // << here !!
// ...
}
а теперь передайте просто вызов
InputField(inputText: $loginViewModel.username, title: "Username:", placeholder: " Enter your username",
hasError: loginViewModel.checkUsernameisValid()) // << here !!
Протестировано с Xcode 12.1 / iOS 14.1
Ответ №2:
Попробуйте:
@ObservedObject var loginViewModel = LoginViewModel()
var inputFields: some View {
VStack {
InputField(inputText: $loginViewModel.username, title: "Username:", placeholder: " Enter your username", hasError: loginViewModel.checkUsernameisValid())
InputField(inputText: $loginViewModel.password, title: "Password:", placeholder: " Enter your password", hasError: loginViewModel.checkUsernameisValid())
}
}
Функция работает с фактическим значением связанной переменной, а не с самой привязкой.