#objective_c #ios #coredata
В наличии UITableView, контент которой заполняется из Core Data при помощи fetchedResultsController'а: - (NSFetchedResultsController *) fetchedResultsController { NSLog(@"fetchedResultsController"); if (fetchedResultsController != nil) { return fetchedResultsController; } NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init]; NSEntityDescription *entity = [NSEntityDescription entityForName:@"Client" inManagedObjectContext:[[PTDataManager sharedManager] managedObjectContext]]; [fetchRequest setEntity:entity]; NSPredicate *predicate = [NSPredicate predicateWithFormat:@"agency_server_id == %@", agency.server_id]; fetchRequest.predicate = predicate; NSSortDescriptor *sortByName1Descriptor = [[NSSortDescriptor alloc] initWithKey:@"lastname" ascending:YES]; NSSortDescriptor *sortByName2Descriptor = [[NSSortDescriptor alloc] initWithKey:@"firstname" ascending:YES]; NSSortDescriptor *sortByName3Descriptor = [[NSSortDescriptor alloc] initWithKey:@"middlename" ascending:YES]; NSArray *sortDescriptors = [[NSArray alloc] initWithObjects: sortByName1Descriptor, sortByName2Descriptor, sortByName3Descriptor, nil]; fetchRequest.sortDescriptors = sortDescriptors; fetchedResultsController = [[NSFetchedResultsController alloc]initWithFetchRequest:fetchRequest managedObjectContext:[[PTDataManager sharedManager] managedObjectContext] sectionNameKeyPath:nil cacheName:nil]; fetchedResultsController.delegate = self; return fetchedResultsController; } другие делегатские методы не реализованы так как таблица заполняется один раз, при входе во viewController и больше не меняется. Стоит задача реализовать поиск по контенту таблицы с отображением в таблице только результатов соответствующих значениям введенным в searchBar. Реализовываю метод: - (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText { [self reloadTableView]; } и соответственно триггеруемый метод для отображения в таблице: - (void)reloadTableView { NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init]; NSEntityDescription *entity = [NSEntityDescription entityForName:@"Client" inManagedObjectContext:[[PTDataManager sharedManager] managedObjectContext]]; [fetchRequest setEntity:entity]; NSPredicate *filterPredicate; NSString *searchString = self.searchBar.text; NSMutableArray *predicateArray = [[NSMutableArray alloc] init]; [predicateArray addObject:[NSPredicate predicateWithFormat:@"agency_server_id CONTAINS[cd] %@", agency.server_id]]; [predicateArray addObject:[NSPredicate predicateWithFormat:@"firstname CONTAINS[cd] %@", searchString]]; [predicateArray addObject:[NSPredicate predicateWithFormat:@"lastname CONTAINS[cd] %@", searchString]]; [predicateArray addObject:[NSPredicate predicateWithFormat:@"middlename CONTAINS[cd] %@", searchString]]; filterPredicate = [NSCompoundPredicate orPredicateWithSubpredicates:predicateArray]; [fetchRequest setPredicate:filterPredicate]; NSSortDescriptor *sortByName1Descriptor = [[NSSortDescriptor alloc] initWithKey:@"lastname" ascending:YES]; NSSortDescriptor *sortByName2Descriptor = [[NSSortDescriptor alloc] initWithKey:@"firstname" ascending:YES]; NSSortDescriptor *sortByName3Descriptor = [[NSSortDescriptor alloc] initWithKey:@"middlename" ascending:YES]; NSArray *sortDescriptors = [[NSArray alloc] initWithObjects: sortByName1Descriptor, sortByName2Descriptor, sortByName3Descriptor, nil]; fetchRequest.sortDescriptors = sortDescriptors; fetchedResultsController = [[NSFetchedResultsController alloc]initWithFetchRequest:fetchRequest managedObjectContext:[[PTDataManager sharedManager] managedObjectContext] sectionNameKeyPath:nil cacheName:nil]; fetchedResultsController.delegate = self; NSError *error = nil; if (![self.fetchedResultsController performFetch:&error]) { NSLog(@"Unresolved error %@, %@", [error localizedDescription], [error localizedFailureReason]); abort(); }; [self.clientsTableView reloadData]; } который похож на fetchedResultsController но как видно имеется отличия в ограничении выборки. Проблема в том, что в таком виде вызов -reloadTableView дергает и сам fetchedResultsController, в результате фетч меняется в процессе ввода символов в searchBar. В таблице появляется все что вытянул fetchedResultsController и плюс все остальное что совпадает с содержимым searchBarа. Визуально: при вводе символов в поле поиска таблица не сокращает количество результатов а увеличивает. Вопрос: на каком этапе реализации поиска по уже фетченой выборке я делаю ошибку? Могу ли я как-то изменить вторичный фетч для поиска по уже полученным из первичного фетча результатам?
Ответы
Ответ 1
Вопрос решился через составной предикат с использованием +orPredicateWithSubpredicates: и +andPredicateWithSubpredicates:: NSPredicate *orPredicate = [NSCompoundPredicate orPredicateWithSubpredicates:[NSArray arrayWithObjects:firstPredicate, secondPredicate, nil]]; NSPredicate *andPredicate = [NSCompoundPredicate andPredicateWithSubpredicates:[NSArray arrayWithObjects:thirdPredicate, fourthPredicate, nil]]; NSPredicate *finalPredicate = [NSCompoundPredicate andPredicateWithSubpredicates:[NSArray arrayWithObjects:orPredicate, andPredicate, nil]]; [fetchRequest setPredicate:finalPredicate]; В таком виде через AND сохраняется результат предварительного фетча и через дополнительные OR происходит его фильтрация согласно критериям поискаОтвет 2
Посмотрите первый ответ, похоже ваша ситуация: How to filter NSFetchedResultsController (CoreData) with UISearchDisplayController/UISearchBar
Комментариев нет:
Отправить комментарий