如何解决SwiftUI:TextField 条件验证
用户可以使用 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))
}
}
解决方法
我所看到的问题是,当您将选择器从绘图更改为地图时,您不会重新计算“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)
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。