WedX - журнал о программировании и компьютерных науках

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

я пытаюсь добавить функцию поиска в свое приложение, используя NSpredicate. я пытался заставить это работать и не могу понять, в чем проблема. я воссоздал демонстрационное приложение, чтобы показать, что я сделал. на симуляторе все отображается без предупреждений, но при наборе текста в строке поиска результатов нет. ничего не отображается в таблице панели поиска. я использую панель поиска и объект контроллера отображения поиска, а также мой исходный источник данных - это простой plist, который содержит словари, и каждый словарь имеет 3 строки. все работает нормально, кроме поиска. может кто-нибудь, пожалуйста, взгляните на мой код и посмотрите, где я ошибся?

вот мой файл .h:

#import <UIKit/UIKit.h>

@interface TableViewController : UITableViewController <UISearchBarDelegate>

@property (strong, nonatomic) NSArray *content;
@property (strong, nonatomic) NSMutableArray *searchResults;

@end

и вот файл .m:

#import "TableViewController.h"
#import "DetailViewController.h"

@interface TableViewController ()

@end

@implementation TableViewController

@synthesize content = _content;
@synthesize searchResults = _searchResults;

-(NSArray *)content
{
if (!_content) {
    _content = [[NSArray alloc] initWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"Data" ofType:@"plist"]];
}
return _content;
}

- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
    // Custom initialization
}
return self;
}

- (void)viewDidLoad
{
[super viewDidLoad];

_searchResults = [[NSMutableArray alloc] init];

}

- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}

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

if (tableView == self.searchDisplayController.searchResultsTableView) {
    return [self.searchResults count];

} else {
    return [self.content count];

}
}

- (void)filterContentForSearchText:(NSString*)searchText scope:(NSString*)scope
{

[_searchResults removeAllObjects];

NSPredicate *resultPredicate = [NSPredicate predicateWithFormat:@"SELF contains[cd] '%@'",searchText];

[_searchResults addObjectsFromArray:[_content filteredArrayUsingPredicate:resultPredicate]];
}

-(BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString
{
[self filterContentForSearchText:searchString
                           scope:[[self.searchDisplayController.searchBar scopeButtonTitles]
                                  objectAtIndex:[self.searchDisplayController.searchBar
                                                 selectedScopeButtonIndex]]];

return YES;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];

if (tableView == self.searchDisplayController.searchResultsTableView) {
    cell.textLabel.text = [_searchResults objectAtIndex:indexPath.row];
    cell.detailTextLabel.text = [_searchResults objectAtIndex:indexPath.row];
} else {
cell.textLabel.text = [[self.content objectAtIndex:indexPath.row] valueForKey:@"city"];
cell.detailTextLabel.text = [[self.content objectAtIndex:indexPath.row] valueForKey:@"state"];
}

return cell;
}



- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if (tableView == self.searchDisplayController.searchResultsTableView) {
    [self performSegueWithIdentifier: @"showDetails" sender: self];
}
}

-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender

{

if ([segue.identifier isEqualToString:@"showDetails"]) {

    NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
    DetailViewController *DVC = [segue destinationViewController];

    if ([self.searchDisplayController isActive]) {

    DVC.cityImageString = [_searchResults objectAtIndex:indexPath.row];
    DVC.cityTextString = [_searchResults objectAtIndex:indexPath.row];
    } else {

        DVC.cityImageString = [[self.content objectAtIndex:indexPath.row] valueForKey:@"cityImage"];
        DVC.cityTextString = [[self.content objectAtIndex:indexPath.row] valueForKey:@"cityText"];
    }

}
}

@end

p.s. я использую xcode 4.6 ios 6, что, я думаю, не имеет значения и может не иметь отношения к моему вопросу, а также я добавил панель поиска через IB, и ее делегат и источник данных были автоматически подключены к представлению таблицы.

большое спасибо за помощь заранее.

Редактировать:

вот структура моего plist, которая очень проста, и я подумал, что это может помочь кому-то предложить мне ответ.

     <?xml version="1.0" encoding="UTF-8"?>
     <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"   "https://www.apple.com/DTDs/PropertyList-1.0.dtd">
       <plist version="1.0">
         <array>
      <dict>
    <key>city</key>
    <string>New York</string>
    <key>state</key>
    <string>NY</string>
    <key>cityText</key>
    <string>This is the description of the city that goes in the tex view just testing.</string>
    <key>cityImage</key>
    <string>acolon.png</string>
       </dict>
       <dict>
    <key>city</key>
    <string>Los Angeles</string>
    <key>state</key>
    <string>CA</string>
    <key>cityText</key>
    <string>This the second item&apos;s textview</string>
    <key>cityImage</key>
    <string>Piedirosso.jpg</string>
     </dict>
      <dict>
    <key>city</key>
    <string>Chicago</string>
    <key>state</key>
    <string>IL</string>
    <key>cityText</key>
    <string>here is the text view description for the third item.</string>
    <key>cityImage</key>
    <string>acolon.png</string>
</dict>
    </array>
    </plist>

  • Есть желающие внести свой вклад? 25.04.2013

Ответы:


1

Ваша проблема - это предикат в этой строке

NSPredicate *resultPredicate = [NSPredicate predicateWithFormat:@"SELF contains[cd] '%@'",searchText];

Ваш массив _content содержит NSDictionaries, которые не поддерживают оператор contains. Кроме того, одинарные/двойные кавычки заставляют %@ использоваться буквально. (Из документов: Single or double quoting variables (or substitution variable strings) cause %@, %K, or $variable to be interpreted as a literal in the format string and so prevent any substitution). Измените это на:

NSPredicate *pred = [NSPredicate predicateWithFormat: @"SELF['city'] contains[cd] %@ OR SELF['state'] contains[cd] %@ OR SELF['cityText'] contains[cd] %@", searchText, searchText, searchText];

(при условии, что вы хотите найти все три значения: город, штат, городтекст)

26.04.2013
  • код, который вы упомянули в своем ответе, не работает. Я загрузил свой проект на github для простоты доступа. не могли бы вы найти время, чтобы посмотреть на него. вот ссылка: github.com/AdrianPhillips/TableSearch 26.04.2013
  • Он отлично работает с вашим кодом. Я заменил строку 59 на то, что я написал в моем ответе и после этого searchResults не пуст. Вы можете проверить это в отладчике. Однако он вылетает, но это потому, что с кодом много других проблем :) 26.04.2013
  • Ну, ты был прав, я забыл, как настроить камеру. я, должно быть, выпил слишком много, пока писал этот проект. :) спасибо за исправления. мне пришлось добавить, чтобы изменить код, который вы мне дали, почти полностью, чтобы заставить его работать правильно, но я должен сказать, что, увидев написанные вами исправления, я увидел, где я был и как добраться туда, куда я хочу быть, так что спасибо, что нашли время. я проверю ваш ответ как правильный. еще раз спасибо 26.04.2013
  • Рад, что смог помочь. Я собираюсь удалить разницу в коде, поскольку она не имеет отношения к этому вопросу. 26.04.2013
  • Конечно вещь. Вы очень помогли. Я обновлю проект на girhub и опубликую ссылку в своем исходном ответе, чтобы другие тоже могли ее использовать. Молодец, молодец, продолжай в том же духе. 26.04.2013

  • 2

    Хорошая работа! но, проверив окончательный код, я обнаружил, что если вы выбираете ячейку из searchResults, всегда отображается первая ячейка, например, для результатов поиска «s»: «Sandiago» и «Sprienfield», если выбрано «Sprienfield», подробное представление будет быть для Сандиаго Я не мог найти ошибку.

    27.05.2013
  • ты прав. я забыл обновить проект в git hub. в основном эта строка отсутствовала в операторе if в переходе, где поиск активен: NSIndexPath *indexPath = [self.searchDisplayController.searchResultsTableView indexPathForSelectedRow]; рад, что вы увидели это, хотя это никогда не было проблемой в моем проекте и было обнаружено и исправлено, но спасибо. 29.05.2013
  • Новые материалы

    Как проанализировать работу вашего классификатора?
    Не всегда просто знать, какие показатели использовать С развитием глубокого обучения все больше и больше людей учатся обучать свой первый классификатор. Но как только вы закончите..

    Работа с цепями Маркова, часть 4 (Машинное обучение)
    Нелинейные цепи Маркова с агрегатором и их приложения (arXiv) Автор : Бар Лайт Аннотация: Изучаются свойства подкласса случайных процессов, называемых дискретными нелинейными цепями Маркова..

    Crazy Laravel Livewire упростил мне создание электронной коммерции (панель администратора и API) [Часть 3]
    Как вы сегодня, ребята? В этой части мы создадим CRUD для данных о продукте. Думаю, в этой части я не буду слишком много делиться теорией, но чаще буду делиться своим кодом. Потому что..

    Использование машинного обучения и Python для классификации 1000 сезонов новичков MLB Hitter
    Чему может научиться машина, глядя на сезоны новичков 1000 игроков MLB? Это то, что исследует это приложение. В этом процессе мы будем использовать неконтролируемое обучение, чтобы..

    Учебные заметки: создание моего первого пакета Node.js
    Это мои обучающие заметки, когда я научился создавать свой самый первый пакет Node.js, распространяемый через npm. Оглавление Глоссарий I. Новый пакет 1.1 советы по инициализации..

    Забудьте о Matplotlib: улучшите визуализацию данных с помощью умопомрачительных функций Seaborn!
    Примечание. Эта запись в блоге предполагает базовое знакомство с Python и концепциями анализа данных. Привет, энтузиасты данных! Добро пожаловать в мой блог, где я расскажу о невероятных..

    ИИ в аэрокосмической отрасли
    Каждый полет – это шаг вперед к великой мечте. Чтобы это происходило в их собственном темпе, необходима команда астронавтов для погони за космосом и команда технического обслуживания..


    Для любых предложений по сайту: [email protected]