对于我的应用程序,我需要用户输入一个介于1到1000之间的数字,并且我想验证它是否介于这些数字之间。起初,我考虑使用Stepper
,但随后用户必须按+
一千次。有一个更好的方法吗?我这样做是为了向用户提示numberPad
,但允许用户输入任何数字。
这是我的代码:
@State var validityPeriod = ""
var body: some View {
NavigationView {
Form {
TextField("Validity Period (In Days)", text: $validityPeriod)
}
.navigationBarTitle("Validation")
}
}
我可以在提交表单之前检查他们输入的数字,但是我希望在他们输入时可以验证字段的内容。
注意:我将Xcode 11.5与Swift 5配合使用
答案 0 :(得分:2)
您可以通过计算出的Bool属性检查当前值是否有效。然后,您可以在任何位置将其签入代码中。
每次您的@State变量更改时,SwiftUI都会重新创建ContentView body
(最好将其私有化,FYI)。它在重新呈现所需内容方面具有一定的智能,但是基本上重新评估了整个View,并且每次击键都会重新计算计算得出的布尔值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
代替。很简单...
请注意,您可能希望帮助人们了解正在发生的事情。如果您的界面尚未清楚可以使用的值,则在挤压无效条目时可能要提供提示。
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")
}
}
}