SearchDisplayController поиск нескольких массивов - PullRequest
1 голос
/ 17 ноября 2011

В настоящее время я заполняю свои ячейки таблицы содержимым нескольких массивов, представляющих имя, идентификатор и т. Д.

Мой вопрос возникает, когда я начинаю использовать контроллер дисплея поиска. У меня есть массив со списком имен, списком идентификаторов, списком штрих-кодов и списком псевдонимов. Когда пользователь вводит в строке поиска, мне нужно иметь возможность искать все 4 массива. Когда он находит результат в 1 массиве, он должен связать результат с 3 другими массивами.

Пример

  1. Имена (яблоко, морковь, банан, собака)
  2. псевдоним (красный, оранжевый, желтый, коричневый)
  3. штрих-код (1,2,10,20)
  4. id (30, 40, 50, 60)

Так что, если пользователь вводит "a", я должен заполнить табличное представление Яблоко, Морковь, Банан и связанный с ним псевдоним, штрих-код, id.

Если пользователь наберет 2, я должен получить только морковка и собака.

Если бы пользователь набрал 0, я бы получил все эти элементы.

Есть идеи, как этого добиться?

UPDATE: Вот как я это сделал.

    -(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;    
}

Затем, когда я заполняю таблицу, я делаю что-то вроде этого

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]];
}

Однако, когда я набираю что-то вроде 9999, это вызывает случаи, когда в идентификаторе или штрих-коде только 1 9. Есть идеи как это исправить?

UPDATE2: Решил проблему, обновляя список всегда, а не перезагружая данные, только если был найден результат. Теперь работает отлично: D

Ответы [ 2 ]

0 голосов
/ 17 ноября 2011

Это можно сделать с помощью NSPredicate, используя объект KVC.

Создать ответ NSObject на схему KVC http://theocacao.com/document.page/161.Для этого вы можете использовать свойство.

Фильтруйте ваш массив с помощью 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];
0 голосов
/ 17 ноября 2011

Контроллер дисплея поиска вызывает

  UISearchDisplayDelegate 

метод:

 searchDisplayController:shouldReloadTableForSearchString:

Внутри этого метода вам нужно реализовать свою логику. Эта логика должна будет искать все 4 ваших массива на предмет попаданий и делать соответствующие поиски (то есть, чтобы добраться от оранжевого до морковного или от 50 до бананового). Каждый раз, когда вы получаете удар, я бы помещал его в NSMutableSet (для предотвращения дублирования). Затем, когда вы закончите поиск по всем массивам, скопируйте набор в массив, из которого считывает источник данных вашей таблицы.

Если вы хотите показать пользователю, ПОЧЕМУ данная строка является хитом (то есть они набрали 50 и получили банан), вам нужно будет отобразить все 4 атрибута в ячейке таблицы. И вам нужно выделить ту часть, которая соответствует. Если вы сделаете это, я бы создал небольшой контейнерный класс, что-то вроде «searchHit», который содержит все 4 атрибута, а также флаг, для которого атрибут получил попадание, и, возможно, подстроку атрибута, который получил попадание (так вы можете использовать желтый фон для этой подстроки, например.) Источник данных tableView будет тогда иметь массив этих объектов searchHit для отображения, и ваш cellForRowAtIndexPath должен будет декодировать этот объект и отобразить попадание соответствующим образом.

...