带有 UiTextField 的 RxSwift

Posted

技术标签:

【中文标题】带有 UiTextField 的 RxSwift【英文标题】:RxSwift With UiTextField 【发布时间】:2021-07-28 13:45:53 【问题描述】:

我是 RxSwift 新手,我正在尝试执行以下操作,

用户类型是搜索UiTextField 应用必须在用户完成输入后等待 1 秒,以确保不会在按下每个字母写入或删除按钮时点击 Api。 应用点击我的 Api 进行搜索

我尝试了以下代码作为示例

class DestinationSearch: UIViewController 
    

    let searchTF = UITextField()    
    var disposeBag = DisposeBag()


    override func viewDidLoad() 
        super.viewDidLoad()

        setUpUI()
        
        
        searchTF.rx.controlEvent(.editingChanged)
            .throttle(.milliseconds(1000), scheduler: MainScheduler.instance)
            .withLatestFrom(searchTF.rx.text)
        .subscribe(onNext: query in
            print(self.hitSomeApi(query: query ?? "--"))
        ).disposed(by: disposeBag)

    

func hitSomeApi(query: String) -> String 
        return query + " Response from API"
    

当我运行应用程序并开始输入时,我会收到 Response from API 消息,每个字母或退格按钮都被按下!为什么throttle 延迟不起作用?我在这里做错了吗?

任何帮助将不胜感激

【问题讨论】:

无法复制。 Response from API 为我每秒钟打印一次,而不是每当我输入字母时。是不是打字太慢了? 也许debounce(而不是throttle)是您要找的? 【参考方案1】:

根据您对问题的描述,debounce 运算符似乎比 throttle 更合适。 debounce 仅在经过一定时间(未发出任何内容)后才发出元素,而 throttle 确保元素至少相隔一定时间间隔发出。

我可以确认您使用 throttle 的代码按我预期的那样工作 - 如果我输入非常快,“来自 API 的响应”消息大约每 1 秒出现一次。如果我打字很慢,慢于每秒 1 次击键,那么只要我按下一个键就会出现消息。换句话说,只要有编辑更改事件,throttle 就会检查是否有一个不到 1 秒前的事件。如果有,请忽略这个新的。

但是如果你使用debounce(相同的代码,只需将throttle 替换为debounce),那么在每次击键后,它会等待1 秒以查看文本字段是否会再次更改。如果它已经等待并且没有更多的编辑更改事件,它只会发出编辑更改事件。因此,如果您继续以高于每秒 1 次击键的速度输入,则 observable 将不会发出任何元素。这似乎是你想要的。

您可以在 RxMarbles 上比较这两个运算符(它们在此处的名称略有不同):

debounceTime throttleTime

【讨论】:

谢谢,使用debounce 解决了我的问题 一般来说,如果 Observable 发出数据,则使用 debounce,如果发出 Void,则使用 throttle。另外,请记住 throttle 将发出“最后一个值”,除非您将该参数设置为 false

以上是关于带有 UiTextField 的 RxSwift的主要内容,如果未能解决你的问题,请参考以下文章

带有查找的 UITextField

带有 UITextField 的 UITableView,滚动错误

单击 UITextField 时带有工具栏的 UIPickerView

以编程方式添加带有约束的 UITextField

如何告诉带有 UITextField 的自定义 UIView 接收触摸事件

带有 Monotouch 的 UITextField ResignFirstResponder 示例