Динамический поиск строки в iOS

от автора

Недавно появилась задача — встроить в приложение динамический поиск информации, то есть выдача должна генерироваться параллельно вводу пользователем символов. Вся информация хранится в SQLite базе данных. Все бы ничего, но в каждом слове выдачи искомые символы должны подсвечиваться.
Было принято волевое решение не использовать внешние библиотеки, а попробовать обойтись своими силами.

Начнем с внешней формы.

В качестве поисковой строки используется UISearchBar. Результаты выводятся в обычный UITableView (в данном случае, с ячейками, кроме текста включающими в себя и картинку).
Обработчиком для события изменения текста в строке является:

- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText {     _data = [SBHotspotData findHotspot:searchText];     [self.searchResultsTableView reloadData]; } 

где _data — NSArray, хранящий результаты выдачи.

На этом этапе возникла проблема — во всех названиях объектов, по которым проводится поиск, есть как заглавные буквы, так и строчные, которые SQLite воспринимает по-разному, а функции lower() и upper(), в отличии от SQL, не поддерживаются. Путем наименьшего сопротивления решили добавить в базу данных отдельный столбец, хранящий в себе все те же заголовки, но уже в нижнем регистре, тем более, что в данном случае увеличение объема базы было практически незаметно. Метод поиска (для работы с БД используется библиотека FMDatabase):

+ (NSArray *) findHotspot: (NSString *)partOfTitle {     SBHotspotData *item;     NSMutableArray *result = [NSMutableArray array];          NSString *path = [self getDatabasePath];     FMDatabase *database;     database = [FMDatabase databaseWithPath:path];     [database open];          NSString *query = [NSString stringWithFormat:@"select * from hotspots where TitleLow like '%%%@%%'", [partOfTitle lowercaseString]];     FMResultSet *results = [database executeQuery:query];          while([results next]) {         item = [[SBHotspotData alloc ]init];         item.hotspotIdentity = [results stringForColumn:@"Identity"];         item.hotspotTitle = [results stringForColumn:@"Title"];         item.hotspotDescription = [results stringForColumn:@"Description"];         [result addObject:item];     }              [database close];      return [result sortedArrayUsingSelector:@selector(compare:)]; }  - (NSComparisonResult)compare:(SBHotspotData *)otherObject {     return [self.hotspotTitle compare:otherObject.hotspotTitle]; } 

При формировании запроса используется %%%@%%, где знаками процента обозначается, что перед и после строки может идти любое количество символов. Метод возвращает массив объектов из базы данных, отсортированный по алфавиту.
Самая интересная часть задания — подсветка введенных символов. Реализуется она следующим образом:

NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:item.hotspotTitle];  NSRange range = [item.hotspotTitle rangeOfString:_searchHotspotBar.text]; [attributedString addAttribute:NSBackgroundColorAttributeName                    value:[UIColor colorWithRed:216/255.0f green:87/255.0f blue:23/255.0f alpha:1.0f]                    range:range];  cell.cellLabel.attributedText = attributedString; 

Для подсветки определенных символов используется NSMutableAttributedString и его метод addAttribute:value:range:.

Ну и результат работы программы:

Задача получилась достаточно тривиальной, но, надеюсь, полученный опыт пригодится кому-либо из хабровчан.

ссылка на оригинал статьи http://habrahabr.ru/post/187512/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *