Вы можете проверить правильность текущего значения с помощью вычисленного свойства Bool. Затем в любом месте вы можете поместить эту проверку в свой код.
SwiftUI воссоздает ContentView body
каждый раз, когда ваша переменная @State изменяется (что лучше всего сделать закрытым, к вашему сведению). У него есть некоторый интеллект в повторном рендеринге только того, что необходимо, но по существу переоценивается весь ваш View, и ваш вычисленный bool periodIsValid
повторно тестируется при каждом нажатии клавиши.
Довольно часто кнопка отправки отключена, пока форма недействительна . Что-то вроде:
Button(...) {
...
}
.disabled(!periodIsValid)
Чтобы сделать это вживую, вы можете сделать ряд творческих вещей с этой живой проверкой. Что-то действительно простое - заставить введенный текст стать красным, если он недействителен:
struct ContentView: View {
@State private var validityPeriod = ""
var periodIsValid: Bool {
guard let days = Int(validityPeriod) else { return false}
guard days >= 1 && days <= 1000 else { return false }
return true
}
var body: some View {
NavigationView {
Form {
TextField("Validity Period (In Days)", text: $validityPeriod)
.foregroundColor(periodIsValid ? .primary : .red)
}
.navigationBarTitle("Validation")
}
}
}
Изменить:
Вы также можете ограничить значения ввода ...
Если подумать об этом подробнее, вы действительно можете выполнить мгновенную проверку текстового поля, что предотвратит ввод недопустимого текста.
Для этого вы используете свойство didSet
обертка. Единственная загвоздка в том, что он не работает с оболочкой @State
, поэтому вам придется использовать вместо него @ObservedObject
. Довольно просто ...
Одно замечание: вы можете помочь людям понять, что происходит. Если ваш интерфейс еще не дает понять, какие значения допустимы, вы можете указать подсказку, когда вы вводите sh недопустимую запись.
class ValidityPeriod: ObservableObject {
@Published var validityPeriod = "" {
didSet {
// Allow blanks in the field, or they can't delete
if validityPeriod == "" { return }
// Check the entire value is good, otherwise ignore the change
let days = Int(validityPeriod) ?? 0
if days < 1 || days > 1000 { validityPeriod = oldValue }
// Pop alert or trigger any other UI instruction here
}
}
}
struct ContentView: View {
@ObservedObject var vp = ValidityPeriod()
var body: some View {
NavigationView {
Form {
TextField("Validity Period (In Days)", text: $vp.validityPeriod)
}
.navigationBarTitle("Validation")
}
}
}