Я реализую поиск с помощью API UISearchController, представленного в iOS 8. У меня есть подкласс UITableViewController, который служит как контроллером результатов поиска, так и средством обновления результатов поиска. Этот контроллер отвечает за отображение результатов поиска в виде таблицы.
Каждый раз, когда текст в searchBar изменяется, API поиска вызывает метод -updateSearchResultsForSearchController: UISearchControllerUpdating на моем контроллере табличного представления. В этом методе я обновляю результаты поиска на основе новой строки поиска, а затем вызываю [self.tableview reloadData].
Я также пытаюсь выделить вхождения строки поиска в списке результатов. Я достигаю этого, устанавливая attributedText в ячейках представления таблицы на строку с атрибутами, которая содержит основные моменты.
Я наблюдаю следующее поведение:
- После первого нажатия клавиши светлые участки отображаются правильно
- После второго нажатия клавиши все блики исчезают, ЗА ИСКЛЮЧЕНИЕМ
- Если ячейка имеет выделенную область в начале строки, она покажет все выделения, даже в остальной части строки.
После некоторых проб и ошибок я обнаружил, что это, похоже, не имеет ничего общего с представлениями таблиц или ячейками и имеет все отношение к UILabel. Кажется, что метки всегда теряют подсветку при второй установке свойства attributedText. Могу ли я установить его только один раз?
Часть моего кода
Источник данных табличного представления:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSString* plainCell = @"plainCell";
UITableViewCell* cell = [self.tableView dequeueReusableCellWithIdentifier:plainCell];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:plainCell];
}
JFDHelpEntry* entry = searchResults[indexPath.row];
cell.textLabel.attributedText = [self highlightedString:entry.title withSearchString:currentSearchString];
return cell;
}
Метод, генерирующий текст, выделяется:
- (NSAttributedString*)highlightedString:(NSString*)string withSearchString:(NSString*)searchString
{
NSMutableAttributedString* result = [[NSMutableAttributedString alloc] initWithString:string];
NSArray* matchedRanges = [self rangesOfString:searchString inString:string];
for (NSValue* rangeInABox in matchedRanges) {
[result addAttribute:NSBackgroundColorAttributeName value:[UIColor yellowColor] range:[rangeInABox rangeValue]];
}
return result;
}
Методы, которые находят диапазоны для выделения:
- (NSArray*)rangesOfString:(NSString*)needle inString:(NSString*)haystack
{
NSMutableArray* result = [NSMutableArray array];
NSRange searchRange = NSMakeRange(0, haystack.length);
NSRange foundRange;
while (foundRange.location != NSNotFound) {
foundRange = [haystack rangeOfString:needle options:NSCaseInsensitiveSearch range:searchRange];
if (foundRange.location != NSNotFound) {
[result addObject:[NSValue valueWithRange:foundRange]];
searchRange.location = foundRange.location + foundRange.length;
}
searchRange.length = haystack.length - searchRange.location;
}
return result;
}
Любые идеи? Спасибо!