我有一个UISearchDisplayController的UISearchBar部分,用于显示来自本地CoreData和远程API的搜索结果. 我想要实现的是在远程API上"延迟"搜索.目前,对于用户键入的每个字符,都会发送一个请求.但是如果用户打字特别快,发送很多请求就没有意义了:等到他停止打字会有所帮助. 有没有办法做到这一点呢?

阅读这documentation条建议等到用户显式点击搜索,但我觉得这对我来说并不理想.

性能问题.如果搜索操作可以非常有效地进行 快速地,可以随着用户的需要更新搜索结果 通过在控件上实现search bar:textDidChange:方法进行键入 委托对象.但是,如果搜索操作花费的时间较长,则 应等到用户轻触搜索按钮后才开始 在searchBarSearchButtonClicked:方法中搜索.始终执行 搜索操作使用后台线程,避免阻塞主 穿线.这将使您的应用程序在搜索时保持对用户的响应 运行,并提供更好的用户体验.

向API发送大量请求不是本地性能的问题,而只是避免远程服务器上的请求率过高的问题.

谢谢

推荐答案

多亏了this link,我找到了一种非常快速和干净的方法.与Nirmit的答案相比,它缺少"加载指示器",但是它在代码行数方面获胜,并且不需要额外的控件.我首先将dispatch_cancelable_block.h文件添加到我的项目中(从this 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]; 
    });
}

注:

  • loadPlacesAutocompleteForInputLPGoogleFunctions库的一部分
  • @implementation外,searchBlockDelay的定义如下:

    静电CGFloat搜索块延迟=0.2;

Ios相关问答推荐

UIImage大小调整工作,但转换为上传数据时恢复到原始大小

实例方法wait在异步上下文中不可用;请改用TaskGroup;这是Swift 6中的错误''

我想在expo 中使用useSafeAreaInsets来获取paddingbottom,但我得到了一个错误

与iPadOS中带有扣件的模式相似的组件是什么?

一堆UIGraphics方法在iOS 17中被弃用,没有明确的替代方法?

如何根据SWIFT中的按钮点击更新文本值

Flutter 应用程序中带有Firebase的GoogleService-Info.plist中缺少CLIENT_ID、REVERSED_CLIENT_ID和ANDROID_CLIENT-ID

iOS应用程序冻结在UICollectionView代码,但我没有';没有任何UICollectionViews

SwiftData共享扩展阻止应用程序打开SQLite文件

动画文本位置

var name: String 时 print(nil) 和 print(name) 的区别? = 无

使用 JSONDecoder 解码的对象的打印输出有问题

Xcode14 启动时崩溃:dyld:库未加载:/usr/lib/swift/libswiftCoreGraphics.dylib

'DismissAction'类型的值没有成员'wrappedValue'在SwiftUI的Xcode中

有哪些可靠的机制可以防止 CoreData CloudKit 中的数据重复?

SensorKit - 获取数据不调用结果委托函数

在 UICollectionView 上从右到左对齐

如何比较两个 UIImage 对象

如何用 CAShapeLayer 和 UIBezierPath 画一个光滑的圆?

Parse for iOS:try 运行应用程序时出错