2011-08-15 39 views
15

我有以下的UISearchBar代碼:如何檢測輸入中的UISearchBar/UITextField的暫停?

- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText 
{ 
    [UIApplication sharedApplication].networkActivityIndicatorVisible = YES; 
    NSString* endpoint =[NSString stringWithFormat:@"http://www.someurl/", 
         [searchText stringByReplacingOccurrencesOfString:@" " withString:@"+"]]; 
    NSURL* url = [NSURL URLWithString:endpoint]; 
    NSURLRequest* request = [NSURLRequest requestWithURL:url]; 
    GTMHTTPFetcher* myFetcher = [GTMHTTPFetcher fetcherWithRequest:request]; 
    [myFetcher beginFetchWithDelegate:self didFinishSelector:@selector(searchResultsFetcher:finishedWithData:error:)]; 
} 

我想給在輸入暫停後該請求,並復位定時器每次一個字符被擊中。我怎樣才能做到這一點?

回答

52

它不必使用NSTimer。

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

      //..... 

      [self performSelector:@selector(request) withObject:nil afterDelay:yourpausetime]; 

     } 
+2

比NSTimer更優雅的解決方案,我想。可能會導致問題取決於runloop和用戶輸入或請求,也許?嗯,不再是一個計時器,雖然 – RSully

+0

不錯!這裏有另一個詳細評論的例子:http://benedictcohen.co.uk/blog/archives/157 – ma11hew28

+0

不起作用,即使我們取消,選擇器也會重複調用(swift 3) – Saif

-1

將文本塊輸入到您的搜索並使NSTimer調用選擇器。顯示某種指標,以便用戶不會認爲出現問題。當選擇器觸發控制回到用戶繼續打字

[NSTimer scheduledTimerWithTimeInterval:0.01 target:self selector:@selector(targetMethod:) userInfo:nil repeats:NO]; 
+0

一羣NSTimers會隨着用戶輸入而關閉。如何在鍵入字符時重置NSTimer? –

+0

我回來了。只有當你想停止射擊計時器時纔會失效。上面的例子重複了:NO,所以它會觸發一次並完成。 = –

+0

我不確定如何在定時器完成之前阻止文本輸入?你能向我展示一個例子嗎? –

6

textDidChange方法中創建一個NSTimer,比如說2秒的值。如果定時器已經存在,則無效並重新創建定時器。 (未經測試的代碼:)

- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText 
{ 
    if (myTimer) { 
     if ([myTimer isValid]) { [myTimer invalidate]; } 
     [myTimer release], myTimer = nil; 
    } 
    myTimer = [[NSTimer scheduledTimerWithTimeInterval:2.0 target:self selector:@selector(userPaused:) userInfo:nil repeats:NO] retain]; 
} 

當用戶停止鍵入2秒,-userPaused:將被調用,您的計時器將自動失效(雖然不爲零)。當用戶開始再次打字時,將設置新的計時器。

+0

像魅力一樣工作! – Wirsing

0

優秀的代碼和完美的工作。我在這裏找到它Replacing an NSTimer with performSelector:withObject:afterDelay由於解決方案......他我只是在這裏複製它所有的恩惠被發現容易

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string 
{ 
    //because the view can be unloaded we must store all data so that its state can be restored in viewDidLoad 
    self.searchQuery = [textField.text stringByReplacingCharactersInRange:range withString:string]; 

    SEL fetchSearchResults = @selector(fetchSearchResults); 

    //cancel the previous search request 
    [[self class] cancelPreviousPerformRequestsWithTarget:self selector:fetchSearchResults object:nil];  

    //perform the search in a seconds time. If the user enters addition data then this search will be cancelled by the previous line 
    [self performSelector:fetchSearchResults withObject:nil afterDelay:1]; 

    return YES; 
} 

- (void)fetchSearchResults 
{ 
    NSLog(@"performing search %@", self.searchQuery); 
    ... 
} 
1

我能斯文談的答案適應斯威夫特我現有的代碼。在我的情況下,我正在將字符串發送給加載搜索結果異步的方法。另外,我沒有使用UISearchBar,而是使用普通的舊UITextField。

var currentTempQuery = "" 

... 

func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool { 
    if let t = textField.text { 
     let s: NSString = t 
     let newString = s.stringByReplacingCharactersInRange(range, withString: string).trim() 

     NSObject.cancelPreviousPerformRequestsWithTarget(self, selector:#selector(MyViewController.sendSearchRequest(_:)), object: currentTermQuery) 

     // Don't replace currentTermQuery until after the cancelPreviousPerformRequestWithTarget call 
     currentTermQuery = newString 
     performSelector(#selector(MyViewController.sendSearchRequest(_:)), withObject: newString, afterDelay: 1) 
    } 
    return true 
} 

這裏是被稱爲選擇:這是在performSelector調用中傳遞,以

func sendSearchRequest(text: String?) { 
    // Call async search method here... 
} 

cancelPreviousPerformRequestsWithTarget作品是你需要傳遞同一個目標,選擇的方式和對象以前的請求被取消。在我的實現中,因爲我傳遞的只是一個字符串,所以我需要在調用之間保留當前的請求字符串,以便我可以引用它來取消請求。

結果適用於在我的UITextField中輸入和刪除字符。每個主要搜索字詞更改僅發送一個搜索。

就像我說的,類似於Sven Tan發佈的,但使用方式略有不同。希望這可以幫助一些人。