我正在做我的第一个 Swift UI 项目。我有一个由视图模型 (vm: SectionFormViewModel
) 支持的表单。我找到了一个巧妙的解决方案来限制此 SO answer 中的数字输入。
struct SectionForm: View {
// @ObservedObject var homeVM: HomeViewModel
@StateObject var vm = SectionFormViewModel()
var body: some View {
// ....
}
var roomVolume: some View {
Section(header: Text("Room Dimensions")) {
if vm.manualArea {
HStack {
// Required to extract to component
// --------------------------------
TextField("Length (feet)", text: $vm.length)
//.keyboardType(.numberPad)
.onReceive(Just(vm.length)) { newValue in
let filtered = newValue.filter { "0123456789".contains($0) }
if filtered != newValue {
vm.length = filtered
}
}
我的想法是创建自己的 NumberField
。它会被这样调用:
NumberField(label: "Length (feet)", binding: $vm.length)
但我不知道具体是怎么做的。
struct NumberField: View {
@Binding var binding: Binding<String>
var body: some View {
TextField("Length (feet)", text: binding)
//.keyboardType(.numberPad)
.onReceive(Just($binding.wrappedValue)) { newValue in
let filtered = newValue.filter { "0123456789".contains($0) }
if filtered != newValue {
$binding.length = filtered
}
}
}
}
首先,有没有可能做这样的事情?
我不认为它可以是 @State
,因为它是在别处定义的。我认为它应该是一个 @Binding
。这可能是显而易见的事情,但经过多次搜索、数小时磨牙、咬指甲和发际线后退,我相信我需要一些帮助。
对不起,标题,我什至不知道如何措辞。我是 Swift 的新手!
答案 0 :(得分:1)
问题是,您已经创建了绑定的绑定。这是错误的。 看到你的代码。有两个绑定。
@Binding var binding: Binding<String>
你的建筑应该是这样的。
struct NumberField: View {
var label: String
@Binding var binding: String
var body: some View {
TextField("Length (feet)", text: $binding)
//.keyboardType(.numberPad)
.onReceive(Just(binding)) { newValue in
let filtered = newValue.filter { "0123456789".contains($0) }
if filtered != newValue {
binding = filtered
}
}
}
}
现在你可以这样使用它
NumberField(label: "Length (feet)", binding: $vm.length)