如何仅当 TextField 中的文本更改时才执行代码

问题描述 投票:0回答:1

我有一个用于搜索数组中的项目的文本字段,并且我正在使用一个模型,该模型具有已发布的文本属性,绑定到该字段以在每次文本更改时调用搜索函数。

我当前的问题是,每当文本字段发生任何事情时,它都会发送一个已更改的通知,因此第一次出现时它会发送一个通知,每次它聚焦、散焦或键入一个字母时它会发送两个通知.

This shows how many times the field sends changes

这是代码的简化示例:

struct ContentView: View {
    @ObservedObject var model = Model()
    @FocusState var focused: Bool

    var body: some View {
        VStack {
            TextField("Field", text: $model.text)
                .submitLabel(.search)
                .focused($focused)

            Text("Field has sent changes \(model.textChanged) times")
            Button(action: { focused = false }) {
                Text("Defocus")
            }
        }
        .padding()
    }
}


class Model: ObservableObject {
    @Published var text: String = ""
    @Published var textChanged: Int = 0

    private var cancellables = Set<AnyCancellable>()

    init() {
        $text
            .sink { text in
                self.textChanged += 1 // This is where i am doing my search call in the actual code
            }
            .store(in: &cancellables)
    }
}

我尝试在 TextField 上使用 .onReceive ,在视图上使用 .onChange($text) 而不是 .sink ,但这并没有改变任何东西。我知道这是 TextField 的默认行为,但我只想在文本更改时执行搜索,而不是每次字段发生问题时执行搜索。将搜索调用放入文本属性的 didSet 中也不是一个选项。

ios swift swiftui textfield
1个回答
0
投票

您可以将

.onChange
附加到
TextField
(或者实际上您可以将其附加到
body
的任何部分):

@State private var counter = 0

var body: some View {
    VStack {
        TextField("Field", text: $model.text)
            .submitLabel(.search)
            .focused($focused)
            .onChange(of: model.text) {
                counter += 1
            }

        Text("Field has sent changes \(model.textChanged) times, counter=\(counter)")
        Button(action: { focused = false }) {
            Text("Defocus")
        }
    }
    .padding()
}
© www.soinside.com 2019 - 2024. All rights reserved.