场景:
在
SwiftUI
中,我的 TextField
有一个 Double
值。点击/聚焦 TextField
时,当前 Double
值将被清除,以便用户可以轻松输入新值,而无需选择和删除当前值。如果用户没有输入新值,则取消选择时将恢复旧值。
利用
.focused()
和 .onChange(of:)
这似乎是不可能的。下面的代码正确地清除了该值(在控制台中可见)。但是,更改并未反映在 UI 中。通过使用 .id()
上的 TextField
强制更新 UI 会取消选择 TextField
,从而使此解决方法毫无用处。
为什么 UI 没有因对
TextField
value 属性的更改而更新?
struct ContentView: View {
@FocusState var focus: Bool
@State var test: Double? = 100
@State var id: UUID = UUID()
var body: some View {
VStack {
TextField("Placeholder", value: $test, format: .number)
.id(id)
.focused($focus)
.onChange(of: focus, perform: { editing in
var oldValue: Double? = test
if editing {
self.$test.wrappedValue = nil
self.$id.wrappedValue = UUID()
} else {
if test == nil {
self.$test.wrappedValue = oldValue
self.$id.wrappedValue = UUID()
}
}
})
}
.padding()
}
}
有没有办法用
SwiftUI
的 TextField
做到这一点?
Why UI not update from the change to the TextField value ?
因为它不会直接将 TextField 的值(String)绑定到您的值(Double)。
对于
clear value on focus, restore on deselect
,您需要在 TextField 上使用文本而不是值进行操作。这是一个例子:
struct TestView: View {
@FocusState var focus: Bool
@State var value: String = "100"
@State private var oldValue: String = ""
var body: some View {
VStack {
TextField("", text: .constant("other"))
TextField("Placeholder", text: $value)
.focused($focus)
.onChange(of: focus) { editing in
if editing {
if !value.isEmpty {
oldValue = value
value = ""
}
} else {
if value.isEmpty {
value = oldValue
}
}
}
}
.textFieldStyle(.roundedBorder)
.padding()
}
}
如果你只想让它成为 Double ,请在外部处理它(在 ViewModel 或其他东西中)
扩展@meomeomeo'答案,请在下面找到一个可重用的
TextField
视图,满足TextField
文本类型为Double
的需要。
第二个
.onChange(of:)
在用户键入时更新输入绑定,但前提是键入的文本属于 Double
类型。这是为了防止用户在之前从未取消选择 TextField
。节省。
struct TextFieldDoubleClearView: View {
@FocusState var focus: Bool
@Binding var input: Double
@State var value: String = "100"
@State private var oldValue: String = ""
var body: some View {
VStack {
TextField("Placeholder", text: $value)
.keyboardType(.decimalPad)
.focused($focus)
.onChange(of: focus, perform: { editing in
if editing {
if !value.isEmpty {
oldValue = value
value = ""
}
} else {
if value.isEmpty {
value = oldValue
} else {
if let valueDouble: Double = Double(value) {
input = valueDouble
} else {
value = oldValue
}
}
}
})
.onChange(of: value, perform: { _ in
if let valueDouble: Double = Double(value) {
input = valueDouble
}
})
}
.padding()
.onAppear {
value = String(input)
}
}
}
用户开始输入后是否可以以某种方式清除文本?我的意思是 TextField 变得聚焦,但用户没有开始输入 - 一旦他开始输入,就显示以前的文本 - 旧文本开始替换为新输入 @meomemeo ??