SearchDisplayController search multiple arrays

*爱你&永不变心* 提交于 2020-01-11 12:45:06

问题


Currently I'm populating my tableviewcells with the contents of multiple arrays representing a name, id, etc.

My question comes when I start to use the search display controller. I have an array with a list of names, a list of IDs, a list of barcodes, and a list of Aliases. When the user types in the search bar I need to be able to search all 4 arrays. When it finds the result in 1 array it has to pair the result with the 3 other arrays..

Example

  1. Names (apple,carrot,banana, dog)
  2. alias (red, orange, yellow, brown)
  3. barcode (1,2,10,20)
  4. id (30, 40, 50, 60)

So if the user types "a" I should populate the table view with Apple, Carrot, Banana and the associated alias, barcode, id.

If the user were to type 2 I should only get carrot and dog.

If the user were to type 0 I would get all of those items.

Any ideas how to accomplish this?

UPDATE: This is how I did it.

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

    BOOL shouldReturn = FALSE;
    [searchResults removeAllObjects];

    for (int i = 0; i < [itemIDRows count]; i++) {

        BOOL foundResult = FALSE;

        if ([[itemIDRows objectAtIndex:i] rangeOfString:searchString].location != NSNotFound) {
            foundResult = TRUE;
        }
        if ([[nameRows objectAtIndex:i] rangeOfString:searchString].location != NSNotFound) {
            foundResult = TRUE;
        }
        if ([[barcodeRows objectAtIndex:i] rangeOfString:searchString].location != NSNotFound) {
            foundResult = TRUE;
        }
        if ([[aliasRows objectAtIndex:i] rangeOfString:searchString].location != NSNotFound) {
            foundResult = TRUE;
        }
        if (foundResult) {
            NSNumber *result = [NSNumber numberWithInt:i];
            if ([self searchResults] == nil) {
                NSMutableArray *array = [[NSMutableArray alloc] init];
                [self setSearchResults:array];
                [array release];
            }
            [searchResults addObject:result];
            shouldReturn = YES;
        }
    }
    return shouldReturn;    
}

Then when I'm populating the tableview I do something like this

if ([tableView isEqual:self.searchDisplayController.searchResultsTableView]) { 
    [cell setCellContentsName:[NSString stringWithFormat:@"%@", [nameRows objectAtIndex:[[searchResults objectAtIndex:indexPath.row] integerValue]]];  
} else {
    [cell setCellContentsName:[NSString stringWithFormat:@"%@", [nameRows objectAtIndex:indexPath.row]];
}

However when I type something like 9999 it brings up instances where only 1 9 is in the ID or barcode. Any ideas how to fix that?

UPDATE2: Solved the problem by having the list always refresh instead of only reloading the data if a result was found. Now it works perfectly :D


回答1:


The search display controller calls the

  UISearchDisplayDelegate 

method:

 searchDisplayController:shouldReloadTableForSearchString:

Inside this method, you need to implement your logic. This logic will need to search all 4 of your arrays for hits, and do the appropriate lookups (i.e. to get from orange to carrot, or from 50 to banana). Each time you get a hit, I would put it in an NSMutableSet (to prevent dupes). Then when you're done searching all arrays, copy the set into the array that your table's data source reads from.

If you want to show the user WHY a given row is a hit (i.e. they typed 50 and got banana), you'd have to display all 4 of the attributes in your table cell. And you'd need to highlight the part that matched. If you do this, I'd create a small container class, something like "searchHit" that contains all 4 attributes, as well as a flag for which attribute got the hit, and possibly the substring of the attribute that got the hit (so you can use a yellow background for this substring, for example.) The tableView's data source would then have an array of these searchHit objects to display, and your cellForRowAtIndexPath would need to decode this object and display the hit appropriately.




回答2:


You can do that with NSPredicate using KVC object.

Create an NSObject respond to the KVC scheme http://theocacao.com/document.page/161 . You can use property for that.

Filter your array with an NSPredicate http://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/NSPredicate_Class/Reference/NSPredicate.html

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"self.name LIKE[cd] %@ OR self.alias LIKE[cd] %@",searchString,searchString];
NSArray *result = [baseArray filteredArrayUsingPredicate:predicate];


来源:https://stackoverflow.com/questions/8169889/searchdisplaycontroller-search-multiple-arrays

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!