观察SwiftUI TextField的变化

6

我在尝试使用Swift UI。我创建了一个列表视图(List),其中包含我所有需要的元素。当按下键盘上的Enter键时,TextField的更改也有效。建立这样一个表格视图是件好事;)

但现在我想要跟踪文本字段上的每一次更改。每当用户输入另一段文本时,我都想发送一个请求来触发搜索。

如何在我的代码中实现这个功能?我也阅读了这里的文档 https://developer.apple.com/documentation/combine/receiving_and_handling_events_with_combine

我不知道如何在我的struct中使用它。

这里提出的解决方案 TextField changes in SwiftUI 不起作用(不再适用)

我将非常感谢您能与我分享的每一个提示和想法。我已经寻找解决方案数小时 :(。

我的代码如下:

import Foundation
import SwiftUI

struct MyListView: View {
    @ObservedObject var viewModel: MyViewModel

    @State private var query = ""

    var body: some View {

        NavigationView {
            List {
                // how to listen for changes here?
                // if I add onEditingChange here, Get the value only after the user finish search (by pressing enter on the keyboard)
                TextField(String.localizedString(forKey: "search_bar_hint"), text: self.$query) {
                    self.fetchListing()
                } 

                ForEach(viewModel.myArray, id: \.id) { arrayObject in
                    MyRow(arrayObj: arrayObject)
                }
            }
            .navigationBarTitle(navigationBarTitle())
        }
        .onAppear(perform: fetchListing)
    }

    private func fetchListing() {
        query.isEmpty ? viewModel.fetchRequest(for: nil) : viewModel.fetchRequest(for: query)
    }

    private func navigationBarTitle() -> String {
        return query.isEmpty ? String.localizedString(forKey: "my_title") : query
    }
}
2个回答

17

一个简单的自定义绑定对于这个任务来说是一个不错的起点:

struct ContentView: View {
    @State private var query = ""

    var body: some View {

        let binding = Binding<String>(
            get: { self.query },
            set: { self.query = $0; self.textFieldChanged($0) }
        )

        return NavigationView {
            List {
                TextField("Text", text: binding)
            }
        }
    }

    private func textFieldChanged(_ text: String) { print(text) }
}

它经过测试并且工作正常


1
太棒了,Mojtaba,非常感谢你的回答。这正是我在寻找的。而且它运行完美。你救了我的一天:)。 - rb90

11

我们开始吧

struct ContentView: View {
    @State private var email = ""
    var body: some View {
        TextField("Email", text: $email)
            .onChange(of: email) { text in
                print(text)
            }
    }
}

2
我得到了以下错误 类型 'TextField<Text>' 的值没有成员 'onChange' - Learn2Code
1
解决方案也可在iOS 14或更高版本中使用。 - C. Skjerdal
这比绑定方法更好。 - Henson Fang

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接