Alterando a ordem de um NSFetchedResultsController on the fly
-
19-09-2019 - |
Pergunta
Eu estou tentando alterar a classificação em um NSFetchController na mosca, por algum tipo de controle segmentado. Para qualquer tipo A-> Z Z-> A coisa do tipo.
O que eu tenho que fazer para fazer isso? Eu estou seguindo o exemplo de Jeff Lamarche aqui: Aqui
Eu preciso fazer um novo NSFetchedResultsController e, em seguida, configurá-lo, ou eu só fazer um novo NSFetchRequest e fazer
fetchedResultController.fetchRequest = newFetchRequest
e então a minha tabela será atualizada automaticamente?
Solução
Eu estava preso com o mesmo problema e eu poderia corrigi-lo com apenas definindo os descritores de classificação em FetchRequest do FetchRequestController, em seguida, executar uma busca (performFetch) e, finalmente, recarregar os dados na exibição de tabela.
NSArray *sortDescriptors = [NSArray arrayWithObject: sorter];
[[fetchedResultsController fetchRequest] setSortDescriptors:sortDescriptors];
NSError *error;
if (![[self fetchedResultsController] performFetch:&error]) {
// Handle you error here
}
[sorter release];
[myTableView reloadData];
Esta foi a maneira mais fácil para mim lidar com a mudança da classificação em tempo real sem deixar cair a FRC ou fazer qualquer outra manipulação fantasia objeto. Não estou certo sobre as implicações de desempenho sobre isso e poderia ter um impacto, se o conjunto de linhas na tabela é enorme.
Outras dicas
Em vez de usar o seu NSFetchedResultsController como fonte de dados de exibição de tabela, criar um NSArray que você defina quando o usuário muda a ordem de classificação com o controle segmentado basear o conteúdo da matriz sobre os resultados obtidos. Em seguida, apenas uma espécie usando ordenação variedade padrão. Algo parecido com isto:
- (IBAction)segmentChanged:(id)sender
{
// Determine which segment is selected and then set this
// variable accordingly
BOOL ascending = ([sender selectedSegmentIndex] == 0);
NSArray *allObjects = [fetchedResultsController fetchedObjects];
NSSortDescriptor *sortNameDescriptor =
[[[NSSortDescriptor alloc] initWithKey:@"name"
ascending:ascending] autorelease];
NSArray *sortDescriptors = [[[NSArray alloc]
initWithObjects:sortNameDescriptor, nil] autorelease];
// items is a synthesized ivar that we use as the table view
// data source.
[self setItems:[allObjects sortedArrayUsingDescriptors:sortDescriptors]];
// Tell the tableview to reload.
[itemsTableView reloadData];
}
Assim, o descritor de tipo que eu usei é chamado de "Nome", mas você mudaria isso para o nome do campo que você deseja classificar nos resultados buscados. Além disso, os itens Ivar eu referenciada seria a sua nova fonte de dados de exibição de tabela. Sua visão mesa delegados agora seria algo como isto:
- (NSInteger)tableView:(UITableView*)tableView
numberOfRowsInSection:(NSInteger)section
{
return [items count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
// Get your table cell by reuse identifier as usual and then grab one of
// your records based on the index path
// ...
MyManagedObject *object = [items objectAtIndex:[indexPath row]];
// Set your cell label text or whatever you want
// with one of the managed object's fields.
// ...
return cell;
}
Não tenho certeza se este é o melhor caminho, mas deve funcionar.
Andreas Schaefer resposta funcionou para mim. O truque está estabelecendo um novo parâmetro para a solicitação de buscar com se é este código:
[[fetchedResultsController fetchRequest] setSortDescriptors:sortDescriptors];
ou
[[fetchedResultsController fetchRequest] setPredicate:predicate];
Antes de chamar o seguinte:
if (![[self fetchedResultsController] performFetch:&error]) {
// Handle you error here
}
[self.tableView reloadData];
parece que quando você definir um novo parâmetro, que o NSFetchedResultsController irá realizar um novo fetchrequest com base no que você definir .. Sem definir um novo parâmetro, não vai realizar a re-fetch e apenas chamando performFetch
ganhou' t trabalho ..
Espero que isso ajude alguém ..
fetchRequest
é uma propriedade só de leitura. A linha de código em seu post não vai funcionar. Se você quiser usar um diferente solicitação de busca, você vai precisar para substituir o controlador com uma nova NSFetchedResultsController
. Sua mesa não vai recarregar automaticamente. Você precisará enviar-lhe uma mensagem reloadData
algum tempo depois de ter substituído o NSFetchedResultsController
.