SwiftUI-如何在TextField上设置最大数量?

时间:2020-05-27 04:02:48

标签: swift swiftui textfield

对于我的应用程序,我需要用户输入一个介于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配合使用

1 个答案:

答案 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")
        }
    }
}