SwiftUI:如何仅在用户停止在 TextField 中输入时运行代码? [英] SwiftUI: How to only run code when the user stops typing in a TextField?

查看:26
本文介绍了SwiftUI:如何仅在用户停止在 TextField 中输入时运行代码?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以我试图制作一个搜索栏,它不会运行显示结果的代码,直到用户停止输入 2 秒(也就是当用户输入新字符时它应该重置某种计时器).我尝试使用 .onChange() 和 AsyncAfter DispatchQueue 但它不起作用(我想我明白为什么当前的实现不起作用,但我不确定我什至以正确的方式解决这个问题)...

so I'm trying to make a search bar that doesn't run the code that displays the results until the user stops typing for 2 seconds (AKA it should reset a sort of timer when the user enters a new character). I tried using .onChange() and an AsyncAfter DispatchQueue and it's not working (I think I understand why the current implementation isn't working, but I'm not sure I'm even attack this problem the right way)...

struct SearchBarView: View {
    @State var text: String = ""
    @State var justUpdatedSuggestions: Bool = false
    var body: some View {
        ZStack {
            TextField("Search", text: self.$text).onChange(of: self.text, perform: { newText in
                appState.justUpdatedSuggestions = true
                DispatchQueue.main.asyncAfter(deadline: .now() + 3, execute: {
                    appState.justUpdatedSuggestions = false
                })
                if justUpdatedSuggestions == false {
                    //update suggestions
                }
            })
        }
    }
}

推荐答案

可能的方法是使用来自 Combine 框架的 debounce.要使用它,最好为搜索文本创建具有已发布属性的分离视图模型.

The possible approach is to use debounce from Combine framework. To use that it is better to create separated view model with published property for search text.

这是一个演示.准备和使用 Xcode 12.4/iOS 14.4 进行测试.

Here is a demo. Prepared & tested with Xcode 12.4 / iOS 14.4.

import Combine

class SearchBarViewModel: ObservableObject {
    @Published var text: String = ""
}

struct SearchBarView: View {
    @StateObject private var vm = SearchBarViewModel()
    var body: some View {
        ZStack {
            TextField("Search", text: $vm.text)
                .onReceive(
                    vm.$text
                        .debounce(for: .seconds(2), scheduler: DispatchQueue.main)
                ) {
                    guard !$0.isEmpty else { return }
                    print(">> searching for: \($0)")
                }
        }
    }
}

这篇关于SwiftUI:如何仅在用户停止在 TextField 中输入时运行代码?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆