UISearchBar检测用户何时停止类型并且不立即搜索,因此检测暂停

Pie*_*ero 17 iphone text uitableview uisearchbar ios

我正在搜索实现一个从网址检索信息的UISearchbar,并使用默认方法:

 - (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText{
Run Code Online (Sandbox Code Playgroud)

我可以立即检测文本何时更改并执行url的获取,但是这样,文本类型很慢,因为iPhone正在搜索url,所以我想在用户停止写入时开始获取url第二,所以我想检测打字的暂停,以刷新通过网址检索信息的表格视图.我找到了这个请求的旧帖子,我尝试了一个解决方案,对我来说不起作用:

- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText
{
    [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(request:)     object:searchText];

    //.....

    [self performSelector:@selector(request:) withObject:searchText afterDelay:1.5];
}

-(void)request:(NSString *)myString
{
    NSLog(@"%@",myString);
}
Run Code Online (Sandbox Code Playgroud)

这样当我输入请求方法时,我没有调用,但是当我停止输入时,我为每个输入的字符调用它,所以默认方法是一样的,我错了什么?或者实施不正确?

rge*_*rge 24

看起来提供的解决方案不起作用,因为cancelPreviousPerformRequestsWithTarget:selector:object:"searchText"参数与前一次调用的"searchText"参数不匹配performSelector:withObject:afterDelay:; 因此,延迟搜索会在每次文本更改时排队,并且永远不会取消.

您可以使用a NSTimer来延迟搜索的调用,并在文本更改时取消计时器:为对象提供NSTimer属性或字段; 在searchBar:textDidChange:取消任何现有的计时器,然后创建并安排一个新的.计时器的目标应该调用您的搜索方法.

像(在我头顶)的东西:

// in your class' .h object fields
{
  ...
  NSTimer *searchDelayer; // this will be a weak ref, but adding "[searchDelayer invalidate], searchDelayer=nil;" to dealloc wouldn't hurt
  ...
}

// in the .m

-(void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText
{
  [searchDelayer invalidate], searchDelayer=nil;
  if (YES /* ...or whatever validity test you want to apply */)
    searchDelayer = [NSTimer scheduledTimerWithTimeInterval:1.5
                                                     target:self
                                                   selector:@selector(doDelayedSearch:)
                                                   userInfo:searchText
                                                    repeats:NO];
}

-(void)doDelayedSearch:(NSTimer *)t
{
  assert(t == searchDelayer);
  [self request:searchDelayer.userInfo];
  searchDelayer = nil; // important because the timer is about to release and dealloc itself
}
Run Code Online (Sandbox Code Playgroud)

一些程序员可能不像我在这里那样对弱引用更不习惯.

[编辑添加:]

如果你设置使用cancelPreviousPerformRequestsWithTarget ......,你可以这样做:

// in your class' .h object fields
{
  ...
  NSString *priorSearchText; // this will NOT be a weak ref, so adding "[priorSearchText release]" to dealloc is also required
  ...
}

// in the .m
-(void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText
{
  [NSObject cancelPreviousPerformRequestsWithTarget:self
                                           selector:@selector(request:)
                                             object:priorSearchText];
  [priorSearchText release], priorSearchText = [searchText retain];
  if (YES /* ...or whatever validity test you want to apply */)
    [self performSelector:@selector(request:)
               withObject:searchText
               afterDelay:1.5];
}
Run Code Online (Sandbox Code Playgroud)

我不认为我曾经使用过cancelPreviousPerformRequestsWithTarget:...是真的,所以我不知道它是否隐藏任何意外.如果您遇到问题,请添加NSLog,查找延迟搜索但不应取消.