在下面的示例中,无论如何修改
userPhoneNumber
,显示的 Textfield's
值都会保持不变,就好像绑定的 getter 值被忽略一样。
@Binding var userPhoneNumber: String
var body: some View {
TextField("", text: Binding(get: {
userPhoneNumber
}, set: { value in
let containsOnlyDigits = value.allSatisfy("0123456789".contains)
guard containsOnlyDigits else {
return
}
userPhoneNumber = value
}))
}
我已放置日志并确认每次都会调用 getter 并且
userPhoneNumber
具有正确的值。
考虑到这一点,可以公平地假设传递常量绑定仍然允许用户修改
Textfield
。
struct ContentView: View {
@State private var value: Binding<String> = .constant("1")
var body: some View {
VStack {
TextField("", text: value)
}
}
}
运行此示例可确认文本字段的输入已被用户修改,即使在模拟器为 iOS 17+ 的情况下传递的绑定是恒定的。在 iOS 17+ 的设备上测试它会复制与模拟器相同的行为。
然而,iOS 16 模拟器并非如此,我敢打赌,运行 iOS 16 的设备上也不会出现这种情况。
如何在 iOS 17 中强制
TextField
尊重绑定的 getter?
您可以使用
.onChange
尝试不同的方法,
仅在文本字段中显示数字。
示例代码:
struct ContentView: View {
@State private var value = "1"
var body: some View {
VStack (spacing: 55) {
Text(value) // <-- for testing
TestingView(userPhoneNumber: $value)
}
}
}
struct TestingView: View {
@Binding var userPhoneNumber: String
var body: some View {
TextField("", text: $userPhoneNumber)
.border(.red)
.onChange(of: userPhoneNumber) { old, new in
if new.allSatisfy("0123456789".contains) {
userPhoneNumber = new
} else {
userPhoneNumber = old
}
}
}
}