2010-01-06 75 views
0

我使用蘋果的示例代碼示例:iPhone - 問題與UITableView中 - 重新加載數據和沒有命中

http://developer.apple.com/iPhone/library/samplecode/TableSearch/index.html

在這個例子中的UITableView在啓動時得到的內容列表。點擊UISearchBar並鍵入內容列表將被過濾,同時檢查ScopeBar的範圍。

我不得不重建這種「即時搜索」到「正常搜索」:開始時我沒有用於TableView的數據。用戶應該點擊SearchBar,鍵入內容,按「搜索」按鈕,搜索請求將被髮送到網絡服務器。網絡服務器的響應將被放入TableView中,用戶可以切換範圍以過濾結果集。更改SearchBar的值不會過濾結果列表。只有按下「搜索」纔會啓動搜索請求。

我拿了示例代碼並重建它(源代碼在底部)。 但我有兩個問題。

  1. 在SearchViewController(帶有TabBar,SearchBar,ScopeBar,TableView)的初始調用中,一切正常。有一個空的TableView。但是,單擊SearchBar並鍵入一個字符,就會出現「沒有命中」的消息。我怎麼能避免這種情況?只有當用戶按下「搜索」並且確實沒有匹配時纔會顯示此消息。
  2. 我的第二個問題:鍵入「hello」並按下「搜索」TableView不會列出結果。如果我點擊「中止」或在不同的範圍,結果將被列出。那麼肯定會有一個像「重新加載」一樣的東西?!

我希望有人能幫助我。 非常感謝&最好的問候。

我的源代碼:

@implementation SearchViewController 

@synthesize listContent, filteredListContent, savedSearchTerm, savedScopeButtonIndex, searchWasActive; 

- (void)viewDidLoad { 
    // restore search settings if they were saved in didReceiveMemoryWarning. 
    if (self.savedSearchTerm) { 
     [self.searchDisplayController setActive:self.searchWasActive]; 
     [self.searchDisplayController.searchBar setSelectedScopeButtonIndex:self.savedScopeButtonIndex]; 
     [self.searchDisplayController.searchBar setText:savedSearchTerm]; 
     self.savedSearchTerm = nil; 
    } 
} 

- (void)viewDidUnload { 
    // Save the state of the search UI so that it can be restored if the view is re-created. 
    self.searchWasActive = [self.searchDisplayController isActive]; 
    self.savedSearchTerm = [self.searchDisplayController.searchBar text]; 
    self.savedScopeButtonIndex = [self.searchDisplayController.searchBar selectedScopeButtonIndex]; 
    self.filteredListContent = nil; 
} 

- (void)dealloc { 
    [listContent release]; 
    [filteredListContent release]; 
    [super dealloc]; 
} 

- (void)setData { 
    self.listContent = [NSMutableArray arrayWithCapacity:3]; 
    [self.listContent addObject:[SearchObjects itemWithType:@"AAA" name:@"Test1"]]; 
    [self.listContent addObject:[SearchObjects itemWithType:@"BBB" name:@"Test2"]]; 
    [self.listContent addObject:[SearchObjects itemWithType:@"BBB" name:@"Test3"]]; 

    // create a filtered list 
    self.filteredListContent = [NSMutableArray arrayWithCapacity:[self.listContent count]]; 
    [self.tableView reloadData]; 
    self.tableView.scrollEnabled = YES; 
} 

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 
    //If the requesting table view is the search display controller's table view, return the count of the filtered list, otherwise return the count of the main list. 
    if (tableView == self.searchDisplayController.searchResultsTableView) { 
     return [self.filteredListContent count]; 
    } else { 
     return [self.listContent count]; 
    } 
} 

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 
    static NSString *kCellID = @"cellID"; 

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellID]; 
    if (cell == nil) { 
     cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:kCellID] autorelease]; 
     cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator; 
    } 

    /* If the requesting table view is the search display controller's table view, configure the cell using the filtered content, otherwise use the main list. */ 
    SearchObjects *searchObject = nil; 
    if (tableView == self.searchDisplayController.searchResultsTableView) { 
     searchObject = [self.filteredListContent objectAtIndex:indexPath.row]; 
    } else { 
     searchObject = [self.listContent objectAtIndex:indexPath.row]; 
    } 
    cell.textLabel.text = searchObject.name; 
    return cell; 
} 

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { 
    // HERE IS THE SOURCE CODE FOR PUSHING TO THE NEXT VIEW 
} 

- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar { 
    // DO SOME CALCULATIONS… AND THE setData METHOD IS CALLED 
} 

- (void)filterContentForSearchText:(NSString*)searchText scope:(NSString*)scope { 
    /* Update the filtered array based on the search text and scope. */ 
    [self.filteredListContent removeAllObjects]; // First clear the filtered array. 

    /* Search the main list for whose type matches the scope (if selected) and whose name matches searchText; add items that match to the filtered array. */ 
    for (SearchObjects *searchObject in listContent) { 
     if ([scope isEqualToString:@"All"] || [searchObject.type isEqualToString:scope]) { 
     NSComparisonResult result = [searchObject.name compare:searchText options:(NSCaseInsensitiveSearch|NSDiacriticInsensitiveSearch) range:NSMakeRange(0, [searchText length])]; 
      if (result == NSOrderedSame) { 
       [self.filteredListContent addObject:searchObject]; 
      } 
     } 
    } 
} 

- (void)filterContentForScope:(NSString*)scope { 
    /* Update the filtered array based on the search text and scope. */ 
    [self.filteredListContent removeAllObjects]; // First clear the filtered array. 

    /* Search the main list for whose type matches the scope (if selected); add items that match to the filtered array. */ 
    for (SearchObjects *searchObject in listContent) { 
     if ([scope isEqualToString:@"All"] || [searchObject.type isEqualToString:scope]) { 
      [self.filteredListContent addObject:searchObject]; 
     } 
    } 
} 

- (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString { 
    [self filterContentForScope:[[self.searchDisplayController.searchBar scopeButtonTitles] objectAtIndex:[self.searchDisplayController.searchBar selectedScopeButtonIndex]]];  
    // Return YES to cause the search result table view to be reloaded. 
    return YES; 
} 

- (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchScope:(NSInteger)searchOption { 
    [self filterContentForScope:[[self.searchDisplayController.searchBar scopeButtonTitles] objectAtIndex:searchOption]]; 
    // Return YES to cause the search result table view to be reloaded. 
    return YES; 
} 
@end 

回答

0

問題已解決,請參閱評論。

0

關於第一個問題,你應該建立一個委託的搜索欄,然後實現– searchBarSearchButtonClicked:,把你的搜索代碼在那裏。您可能還必須實施其他方法,如– searchBarTextDidEndEditing:– searchBar:textDidChange:,並確保它們不執行搜索。

對於第二個問題,您可能需要重新使用– searchBarSearchButtonClicked:中的委託重新載入tableView,以確保它在搜索完成後發生。您可以使用[tableView reloadData]來完成此操作。

+0

嗯,我不明白。我已經有一個方法「searchBarSearchButtonClicked:」。在這我發送請求t服務器和「setData」方法設置數據到TableView並執行reloadData,但這是行不通的。 – Tim 2010-01-07 09:24:57

+0

您是否重寫了searchBarTextDidChange以防止可能重新加載數據? – mjdth 2010-01-07 14:47:32

+0

我解決了這個問題。我設置了一個標誌,並且只有標誌爲真,表示搜索已完成,然後返回YES;在委託方法searchDisplayController:controller shouldReloadTableFor ... 另一個問題是在listContent中。它執行reloadData,但重點放在filteredContentList上! – Tim 2010-01-07 19:44:26