【发布时间】:2020-04-07 05:04:17
【问题描述】:
我正在尝试通过使用正则表达式删除某些字符来验证 TextField 中的用户输入。不幸的是,我遇到了 text var 递归调用自身的 didSet 方法的问题。
import SwiftUI
import Combine
class TextValidator: ObservableObject {
@Published var text = "" {
didSet {
print("didSet")
text = text.replacingOccurrences(
of: "\\W", with: "", options: .regularExpression
) // `\W` is an escape sequence that matches non-word characters.
}
}
}
struct ContentView: View {
@ObservedObject var textValidator = TextValidator()
var body: some View {
TextField("Type Here", text: $textValidator.text)
.padding(.horizontal, 20.0)
.textFieldStyle(RoundedBorderTextFieldStyle())
}
}
在swift docs(参见 AudioChannel 结构)中,Apple 提供了一个示例,其中在其自己的 didSet 方法中重新分配了一个属性,并明确指出这不会导致再次调用 didSet 方法。我在操场上做了一些测试并确认了这种行为。但是,当我使用 ObservableObject 和 Published 变量时,情况似乎有所不同。
如何防止 didSet 方法递归调用自身?
我尝试了post 中的示例,但没有一个有效。从那时起,Apple 可能已经改变了一些事情,所以这篇文章不是那个重复的。
此外,在遇到无效字符时在 didSet 方法中将文本设置回 oldValue 意味着如果用户粘贴文本,则整个文本将被删除,而不是仅删除无效字符。所以这个选项不起作用。
【问题讨论】: