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

时间:2012-03-10 00:26:07

标签: iphone ios uitableview text uisearchbar

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

 - (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText{

我可以立即检测到文本更改并执行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);
}

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

2 个答案:

答案 0 :(得分:24)

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

您可以使用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
}

有些程序员可能不像我在这里那样使用弱引用。

[已编辑添加:]

如果你设置使用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];
}

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

答案 1 :(得分:0)

移动此行: [self performSelector:@selector(request:) withObject:searchText afterDelay:1.5]; 超出您的textDidChange方法并将其放入文本中,开始编辑方法: - (void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar