【问题标题】:SwiftUI: TextField conditional validationSwiftUI:TextField 条件验证
【发布时间】:2021-09-02 04:31:35
【问题描述】:

用户可以使用 TextFields 提供一些数字输入。如果选择器设置为“绘图”,则任何有效数字都可以,但如果将其设置为“地图”,则验证必须将数字限制在(在这种情况下)-180 和 +180 之间。好的数字显示绿色轮廓,坏数字显示红色。

在选择器更改之前,我可以很好地处理验证。例如1234 的输入对于“绘图”来说很好,但切换到“地图”仍然会显示绿色,如果不是这样的话。 The same is true when an invalid "map" number (showing red) remains invalid when the picker is changed to "plot".无论焦点是否在特定的 TextField 上都是如此。

我已将其缩减为以下演示问题的少量代码。我不确定我的逻辑是否错误,或者我只是没有正确实施它。任何帮助表示赞赏。

struct ContentView: View {

   @StateObject var addPatternVM = AddPatternVM()

   var body: some View {
       VStack {
           Picker(selection: $addPatternVM.type, label: Text("")) {
               Text("Plot").tag("plot")
               Text("Map").tag("map")
           }.pickerStyle(SegmentedPickerStyle())
           TextField(addPatternVM.type == "plot" ? "Minimum x" : "Minimum longitude", text: $addPatternVM.minimumXString)
               .textFieldStyle(BorderedTextView(isGood: addPatternVM.minimumXIsGood))
               .onChange(of: addPatternVM.minimumXString) { newValue in
                   addPatternVM.isMinimumXGood(newValue: newValue)
               }
       }.padding()
   }
}

我的简化视图模型:

class AddPatternVM: ObservableObject {

   @Published var type: String = "plot"
   @Published var minimumXIsGood = false
   @Published var minimumXString = ""

   func isMinimumXGood(newValue: String) {
       if type == "plot" {
           if numberIsGood(newValue: newValue) {
               minimumXIsGood = true
           } else {
               minimumXIsGood = false
           }
       } else if type == "map" {
           if longitudeIsGood(newValue: newValue) {
               minimumXIsGood = true
           } else {
               minimumXIsGood = false
           }
       }
   }

   func numberIsGood(newValue: String) -> Bool {
       return Double(newValue) != nil ? true : false
   }

   func longitudeIsGood(newValue: String) -> Bool {
       guard let longitude = Double(newValue) else { return false }
    
       if longitude < -180.0 || longitude > 180.0 {
           return false
       } else {
           return true
       }
   }
}

这只是我用来显示有效/无效输入的 TextFieldStyle。

struct BorderedTextView: TextFieldStyle {

   var isGood: Bool

   public func _body(
       configuration: TextField<Self._Label>) -> some View {
       return configuration
           .padding(EdgeInsets(top: 8, leading: 16, bottom: 8, trailing: 16))
           .background(Color.white)
           .overlay(RoundedRectangle(cornerRadius: 8)
                       .stroke(lineWidth: 1)
                       .foregroundColor(isGood ? .green : .red))
   }
}

【问题讨论】:

    标签: validation swiftui textfield


    【解决方案1】:

    我看到的问题是,当您将选择器从绘图更改为地图时,您没有重新计算“minimumXIsGood”值,反之亦然。试试这个:

        Picker(selection: $addPatternVM.type, label: Text("")) {
            Text("Plot").tag("plot")
            Text("Map").tag("map")
        }.pickerStyle(SegmentedPickerStyle())
        .onChange(of: addPatternVM.type) { _ in
            addPatternVM.isMinimumXGood(newValue: addPatternVM.minimumXString)
        }
    

    【讨论】:

    • 非常感谢您。我只是看不到我的(不正确的)假设,即更改 ObservableObject 会触发重绘并更新 TextField。当然逻辑不存在它在选择器中!再次感谢。
    猜你喜欢
    • 2011-02-25
    • 1970-01-01
    • 2012-12-30
    • 2012-10-12
    • 2011-01-06
    • 2011-10-27
    • 2015-05-14
    • 2014-04-24
    • 1970-01-01
    相关资源
    最近更新 更多