一尘不染

如何在iOS UISearchBar中限制搜索(基于键入速度)?

swift

我有UISearchDisplayController的UISearchBar部分,该部分用于显示来自本地CoreData和远程API的搜索结果。我要实现的是在远程API上进行搜索的“延迟”。当前,对于用户键入的每个字符,都会发送一个请求。但是,如果用户输入速度特别快,那么发送许多请求就没有意义:这将有助于等待用户停止输入。有办法实现吗?

阅读文档建议您等到用户明确点击搜索后,但就我而言,它并不理想。

性能问题。如果可以非常快速地执行搜索操作,则可以通过在委托对象上实现searchBar:textDidChange:方法来更新用户输入时的搜索结果。但是,如果搜索操作花费更多时间,则应等到用户点按“搜索”按钮,然后才能在searchBarSearchButtonClicked:方法中开始搜索。始终在后台线程中执行搜索操作,以避免阻塞主线程。这样可以在搜索运行时使您的应用对用户保持响应,并提供更好的用户体验。

向API发送许多请求不是本地性能的问题,而仅仅是避免远程服务器上的请求率过高。

谢谢


阅读 281

收藏
2020-07-07

共1个答案

一尘不染

通过此链接,我找到了一种非常快捷,干净的方法。与Nirmit的答案相比,它缺少“加载指示器”,但是在代码行数方面胜出,并且不需要其他控件。我首先将该dispatch_cancelable_block.h文件添加到了我的项目(来自此repo),然后定义了以下类变量:__block dispatch_cancelable_block_t searchBlock;

我的搜索代码现在看起来像这样:

- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText
{
    if (searchBlock != nil) {
        //We cancel the currently scheduled block
        cancel_block(searchBlock);
    }
    searchBlock = dispatch_after_delay(searchBlockDelay, ^{
        //We "enqueue" this block with a certain delay. It will be canceled if the user types faster than the delay, otherwise it will be executed after the specified delay
        [self loadPlacesAutocompleteForInput:searchText]; 
    });
}

笔记:

  • loadPlacesAutocompleteForInput是金LPGoogleFunctions
  • searchBlockDelay在之外定义如下@implementation

静态CGFloat searchBlockDelay = 0.2;

2020-07-07