Core Data, Search Controller and Table View
I have integrated the search function to my app to query core data/.sqlite and it works ok. But I have a problem and I am not sure which class configuration should I look at, could someone points me to the light, thanks
Basically my model is this
TableView 1
Display Product Category selectRow --> TableView2TableView 2
Display Products of selected Category selectRow --> TableView3As I integrated the UISearchBar in TableView 1, I wish to have the function when people search the product they want and it will show up the product's name right away in the table view. I tried, but the result is showing the Category which contains the "searched product".
So, how could I get this to show up correctly and which section of configuration should I look at?
UISearchDisplayController *searchDisplayController = [[UISearchDisplayController alloc] initWithSearchBar:searchBar contentsController:self];
[self performSelector:@selector(setSearchDisplayController:) withObject:searchDisplayController];
[searchDisplayController setDelegate:self];
[searchDisplayController setSearchResultsDataSource:self];
[searchDisplayController setSearchResultsDelegate:self];
[searchDisplayController release];
[self.tableView setContentOffset:CGPointMake(0,self.searchDisplayController.searchBar.frame.size.height)];
NSError *error = nil;
if (![[self fetchedResultsController] performFetch:&error]) {
/*
Replace this implementation with code to hand开发者_如何学Gole the error appropriately.
abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development. If it is not possible to recover from the error, display an alert panel that instructs the user to quit the application by pressing the Home button.
*/
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
abort();
self.filteredListContent = [NSMutableArray arrayWithCapacity:[[[self fetchedResultsController] fetchedObjects] count]];
}
Is it this part of the code?
ThanksUpdate with more info:
Configure Cell
- (void)configureCell:(UITableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath {
NSManagedObject *entity = nil;
if (self.searchIsActive){ // Configure the cell to show the searched item's name
entity = [[self filteredListContent] objectAtIndex:[indexPath row]];
cell.textLabel.textColor = [UIColor blackColor];
} else {// Configure the cell to show the category's name
cell.textLabel.textColor = [UIColor blackColor];
entity = [fetchedResultsController objectAtIndexPath:indexPath];
}
cell.textLabel.text = [entity valueForKey:@"nameEN"];
}
The Search Predicate
- (void)filterContentForSearchText:(NSString*)searchText scope:(NSString*)scope {
NSPredicate * predicate = [NSPredicate predicateWithFormat:@"ANY products.nameEN CONTAINS[cd] %@", searchText];
self.filteredListContent = [[[self fetchedResultsController] fetchedObjects] filteredArrayUsingPredicate:predicate];
}
The Core Data Structure
Category{
nameEN
products <- one to many relation ->> Product.productcat
}
Product{
nameEN
spec
productcat <<-- many to one relation-> Category.products
}
Thank you.
If your data model has a Product
entity and a Category
entity and your fetches are returning Category
objects instead of Product
objects, then you have the wrong entity set for your fetch.
[ignore following as it applies to a different type of search -- techzen]
You usually create a separate fetch for the search because every time the users enters new characters in the search, the predicate for the fetch must change.
Update:
Okay, I misunderstood the type of search you were implementing. You are filtering the return of an existing fetch instead of fetching based on the entered search.
Looking at the predicate and data model in your update I think it clear that the predicate will only work against an array of Category
objects. This:
NSPredicate * predicate = [NSPredicate predicateWithFormat:@"ANY products.nameEN CONTAINS[cd] %@", searchText];
... can only filter Category
objects because only the Category
object has an attribute of products
. This predicate says, "Match all Catergory objects in which any related Product object has a nameEn attribute value that contains the search text."
Remember as well that the array you are filtering here:
self.filteredListContent = [[[self fetchedResultsController] fetchedObjects] filteredArrayUsingPredicate:predicate];
...is an array of Category
objects and not Product
objects.
I think you need to rethink your UI design. Your TableView1 defaults to displaying a list of Category
objects but you want your search of that table to display a list of Product
objects. That will confuse the user. The user will expect a search on a table of Category
objects to return a subset of Category
objects.
However, with the existing design, you can produce an array of Product
objects with the current code by creating a new array of Product
objects by apply the @distinctUnionOfObjects
collection operator:
self.filteredListContent = [[[self fetchedResultsController] fetchedObjects] filteredArrayUsingPredicate:predicate];
NSArray *distinctProducts=[self.filteredListContent valueForKey:@"products.@distinctUnionOfObjects.enName"];
... distinctProducts
will now be an array of Product
objects matching the search criteria. Use that array in configureCell:atIndexPath
(you may need to resort it.)
So, I tried these at the configure cell part
NSDictionary *distinctProducts=[self.filteredListContent valueForKey:@"products"];
NSLog(@"what are products:%@",distinctProducts);
NSArray *listofProductsName = [distinctProducts valueForKey:@"nameEN"];
NSLog(@"whatup: %@",listofProductsName);
NSArray *entity = [listofProductsName objectAtIndex:indexPath.row];
cell.textLabel.textColor = [UIColor blackColor];
cell.textLabel.text = entity;
But then I could convert the name to show...it said _NFSet isEqualToString: ....etc terminated NSException.. though the NSLog of listofProductsName show up the right products name list.
精彩评论