开发者

Core Data, Search Controller and Table View

开发者 https://www.devze.com 2023-02-15 14:00 出处:网络
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 t

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 --> TableView2

TableView 2

Display Products of selected Category

selectRow --> TableView3

As 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?

Thanks

Update 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.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号