#iphone #search #core-data #nsfetchedresultscontroller
#iPhone #Поиск #core-данные #nsfetchedresultscontroller
Вопрос:
Я хочу добавить возможность поиска в моей базе данных core data.
У меня есть табличное представление с пользовательской ячейкой, но их всего 8, и они недоступны для редактирования.
Теперь я добавил панель поиска с searchDisplayController в заголовок TableView, и я хочу использовать NSFetchedResultsController
для управления данными поиска.
Я пытался написать этот код, но он не работает…
-(void)createSearch
{
UISearchBar *searchBar = [[UISearchBar alloc] initWithFrame:CGRectMake(0, 0, 320, 44)];
searchBar.delegate = self;
searchBar.scopeButtonTitles = [NSArray arrayWithObjects:@"All", @"Title", @"Notes", @"Tags", nil];
searchBar.showsScopeBar = YES;
self.tableView.tableHeaderView = searchBar;
[searchBar setBackgroundImage:[UIImage imageNamed:@"navbarBg"]];
searchController = [[UISearchDisplayController alloc] initWithSearchBar:searchBar contentsController:self];
searchController.delegate = self;
searchController.searchResultsDataSource = self;
searchController.searchResultsDelegate = self;
}
-(NSFetchedResultsController *)searchResultsController
{
if (searchResultsController != nil)
{
return searchResultsController;
}
NSFetchRequest *request = [[NSFetchRequest alloc] initWithEntityName:@"Task"];
[request setFetchBatchSize:20];
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"title" ascending:YES];
NSArray *descriptors = [NSArray arrayWithObject:sortDescriptor];
[request setSortDescriptors:descriptors];
NSFetchedResultsController *afrc = [[NSFetchedResultsController alloc] initWithFetchRequest:request managedObjectContext:self.managedObjectContext sectionNameKeyPath:nil cacheName:nil];
afrc.delegate = self;
searchResultsController = afrc;
return searchResultsController;
}
-(void)controllerWillChangeContent:(NSFetchedResultsController *)controller
{
[self.searchController.searchResultsTableView beginUpdates];
}
-(void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(NSIndexPath *)newIndexPath
{
UITableView *tableView = self.searchController.searchResultsTableView;
switch(type)
{
case NSFetchedResultsChangeInsert:
[tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
break;
case NSFetchedResultsChangeDelete:
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
break;
case NSFetchedResultsChangeUpdate:
[self configureCell:[self tableView:tableView cellForRowAtIndexPath:indexPath] toIndexPath:indexPath];
break;
case NSFetchedResultsChangeMove:
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
[tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath]withRowAnimation:UITableViewRowAnimationFade];
break;
}
}
-(void)controller:(NSFetchedResultsController *)controller didChangeSection:(id<NSFetchedResultsSectionInfo>)sectionInfo atIndex:(NSUInteger)sectionIndex forChangeType:(NSFetchedResultsChangeType)type
{
UITableView *tableView = self.searchController.searchResultsTableView;
switch (type)
{
case NSFetchedResultsChangeInsert:
[tableView insertSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];
break;
case NSFetchedResultsChangeDelete:
[tableView deleteSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];
break;
}
}
-(void)controllerDidChangeContent:(NSFetchedResultsController *)controller
{
[self.searchController.searchResultsTableView endUpdates];
}
-(void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText
{
NSPredicate *predicate = nil;
if (self.searchController.searchBar.selectedScopeButtonIndex == 0)
{
predicate = [NSPredicate predicateWithFormat:@"1=1"];
}
else if (self.searchController.searchBar.selectedScopeButtonIndex == 1)
{
predicate = [NSPredicate predicateWithFormat:@"title CONTAINS[c] %@", searchText];
}
else if (self.searchController.searchBar.selectedScopeButtonIndex == 2)
{
predicate = [NSPredicate predicateWithFormat:@"notes CONTAINS[c] %@", searchText];
}
/*else
{
predicate = [NSPredicate predicateWithFormat:@"tags
}*/
[self.searchResultsController.fetchRequest setPredicate:predicate];
[self.searchController.searchResultsTableView reloadData];
}
И это методы делегирования TableView и DataSource:
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
if (tableView == self.searchController.searchResultsTableView)
{
return [[self.searchResultsController sections] count];
}
else
{
return 1;
}
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if (tableView == self.searchController.searchResultsTableView)
{
id <NSFetchedResultsSectionInfo> sectionInfo = [[self.searchResultsController sections] objectAtIndex:section];
return [sectionInfo numberOfObjects];
}
else
{
return 8;
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
if (tableView == self.searchController.searchResultsTableView)
{
static NSString *SearchCellIdentifier = @"SearchCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:SearchCellIdentifier];
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:SearchCellIdentifier];
}
[self configureCell:cell toIndexPath:indexPath];
return cell;
}
else
{
static NSString *CellIdentifier = @"Cell";
MainTableCell *cell = (MainTableCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[MainTableCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
cell.accessoryView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"accessoryView"]];
}
[self configureCell:cell fromArray:cellImages toIndexPath:indexPath];
return cell;
}
}
Почему это не работает?
Большое вам спасибо 😉
Комментарии:
1. Укажите «не работает».
2. Я не получаю ошибок, но когда я пытаюсь написать букву или слово, вместо задачи отображаются все задачи, которые фильтруются с помощью предиката
Ответ №1:
в конце вашей панели поиска: textDidChange: сообщение прямо перед вызовом reloadData:
[Выпуск searchResultsController]; searchResultsController = nil;
Комментарии:
1. Да, я прочитал ваш ответ, но в моей ситуации мне не нужны два NSFetchedResultsController, потому что я использую его только для выполнения поиска.
2. вы пробовали взламывать свой FEC, а затем, когда вы создаете FRC, вы применяете предикат. Есть только несколько вещей, которые вы можете изменить после сборки FRC.
3. Нет, я не пробовал, но я не совсем понял, что вы хотите сказать… Можете ли вы мне объяснить? Спасибо 😉