2

だから私は現在、検索バーからのテキストの変更を聞いています:

-(void)searchBar:(UISearchBar*)searchBar textDidChange:(NSString*)searchText
{    
      [self filterContentForSearchText:searchText]; 
}

filterContentForsearchText入力時に UITableView を自動的にフィルタリングするようなメソッドを設計したいと考えています。

私が抱えている問題は、私の UITableView が複雑であることです。複数のフィールドを持つ複数のセクションがあります。基本的には、連絡先オブジェクトを保持する配列の配列である連絡先/アドレス帳です。

CustomContact *con = [contacts[section_of_contact] allValues][0][x]x はそのセクションの特定の行で、次のようなプロパティを持つ CustomContact "con" を返しますcon.fullName

UITableView は現在、連絡先のフルネームを別々のセクションに表示しています。my を使用して入力するときに、配列/UITableView のこの構造をどのようにフィルター処理できますUISearchBarか?

テーブルを埋める方法は次のとおりです。

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    BrowseContactCell *cell = [tableView dequeueReusableCellWithIdentifier:@"BROWSECELL"];

    CustomContact *thisContact = [self.contacts[indexPath.section] allValues][0][indexPath.row];

        cell.labelName.text = thisContact.fullName;

return cell;
}
4

1 に答える 1

4

セクション (配列の配列) を含むアドレス帳も作成したので、ソリューションを投稿しますが、これは私自身のソリューションではありません (少し前にスタックオーバーフローのどこかで見つけました)。

UITableViewControllerサブクラスで、次の 2 つのメソッド (API リファレンスへのリンク) と「カスタム」メソッドを追加してUISearchDisplayDelegate配列filterContentForSearchTextフィルター処理します。理解を深めるために、コード ブロック内の私のコメントをお読みください。さらなる質問や改善のためのアイデアはいつでも歓迎します。

#pragma mark - search Display Controller Delegate

- (BOOL) searchDisplayController : (UISearchDisplayController *) controller
shouldReloadTableForSearchString : (NSString *) searchString {

    [self filterContentForSearchText : searchString
                               scope : [[self.searchDisplayController.searchBar scopeButtonTitles]
                       objectAtIndex : [self.searchDisplayController.searchBar selectedScopeButtonIndex]]];
    return YES;
}

#pragma mark - Search Filter

- (void) filterContentForSearchText : (NSString*) searchText
                              scope : (NSString*) scope {
    // Here, instead of "lastName" or "firstName" just type your "fullName" a.s.o.
    // I have also a custom NSObject subclass like your CustomContact that holds 
    //these strings like con.firstName or con.lastName
    NSPredicate* resultPredicate = [NSPredicate predicateWithFormat : @" (lastName beginswith %@) OR (firstName beginsWith %@)", searchText, searchText];

    // For this method, you just don't need to take your partitioned and 
    // somehow complicated contacts array (the array of arrays). 
    // Instead, just take an array that holds all your CustomContacts (unsorted):
    NSArray* contactsArray = // here, get your unsorted contacts array from your data base or somewhere else you have stored your contacts;

    // _searchResults is a private NSArray property, declared in this .m-file 
    // you will need this later (see below) in two of your UITableViewDataSource-methods:
    _searchResults = [contactsArray filteredArrayUsingPredicate : resultPredicate];

    // this is just for testing, if your search-Filter is working properly.
    // Just remove it if you don't need it anymore
    if (_searchResults.count == 0) {
        NSLog(@" -> No Results (If that is wrong: try using simulator keyboard for testing!)");
    } else {
        NSLog(@" -> Number of search Results: %d", searchResults.count);
    }
}

UITableViewDataSourceここで、次の 3 つのメソッドにいくつかの変更を加える必要があります。

: searchResultsTableView は、(セクション化されたアドレス帳の)tableView を埋めるために通常呼び出される通常の一般的なデータ ソース メソッドでも読み込まれます。

1.

- (NSInteger) numberOfSectionsInTableView : (UITableView *) tableView
{
    if (tableView == self.searchDisplayController.searchResultsTableView) {
         // in our searchTableView we don't need to show the sections with headers
        return 1;
    }
    else {
        return [[[UILocalizedIndexedCollation currentCollation] sectionTitles] count];
    }
}

2.

- (NSInteger) tableView : (UITableView *) tableView
  numberOfRowsInSection : (NSInteger) section {

    if (tableView == self.searchDisplayController.searchResultsTableView) {
        // return number of search results
        return [_searchResults count];
    } else {
        // return count of the array that belongs to that section
        // here, put (or just let it there like before) your 
        // [contacts[section] allValues][count]
       return [[currentMNFaces objectAtIndex : section] count];
    }    
}

3.

- (UITableViewCell*) tableView : (UITableView *) tableView
          cellForRowAtIndexPath : (NSIndexPath *) indexPath {

    BrowseContactCell *cell = [tableView dequeueReusableCellWithIdentifier:@"BROWSECELL"];
CustomContact *thisContact = nil;

    // after loading your (custom) UITableViewCell
    // you probably might load your object that will be put into the 
    // labels of that tableCell.
    // This is the point, where you need to take care if this is your
    // address-book tableView that is loaded, or your searchTable:

    // load object...    
    if (tableView == self.searchDisplayController.searchResultsTableView) {
        // from search list
        faceAtIndex = [self->searchResults objectAtIndex: indexPath.row];
    } else {
        // from your contacts list
        contactAtIndex = [self.contacts[indexPath.section] allValues][0][indexPath.row];
    }

    }

それがうまくいくことを願っています。

于 2013-06-11T12:08:35.187 に答える