ggg22
ggg22

Reputation: 23

Adding a Search Bar to a Table View with Core Data

I have an app that saves data to a Core Data sql then view it in a table view.

The data model:

Entity: Fruits

Attributes:  name, picture

So in the table view, cell.textLabel.text = Fruits.name

Each cell has a segue with a view that shows Fruits.picture.

I want to add a search bar to search in Fruits names.

I followed this tutorial: http://www.appcoda.com/search-bar-tutorial-ios7/

But the problem I had is in filterContentForSearchText

- (void)filterContentForSearchText:(NSString*)searchText scope:(NSString*)scope
{
    NSPredicate *resultPredicate = [NSPredicate predicateWithFormat:@"name contains[c] %@", searchText];
    searchResults = [recipes filteredArrayUsingPredicate:resultPredicate];
}

I'm using core data not an array for storing data. And I don't know how to filter it so I can display searchResults in table cells and use it in prepareForSegue.

Upvotes: 1

Views: 4165

Answers (2)

Ayu
Ayu

Reputation: 954

Since you're using core data and not an array of Fruits you should filter your data this way:

- (void)filterContentForSearchText:(NSString*)searchText scope:(NSString*)scope
{
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];

    NSEntityDescription *entity = [NSEntityDescription
                                   entityForName:@"Fruits" inManagedObjectContext:managedObjectContext];
    [fetchRequest setEntity:entity];
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name contains[c] %@", searchText];
    [fetchRequest setPredicate:predicate];

    NSError *error;

    NSArray* searchResults = [managedObjectContext executeFetchRequest:fetchRequest error:&error];
}

To show the picture in a second viewController you should put something like this in you prepareForSegue method:

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    Fruit *selectedItem;
    if (self.searchDisplayController.active) {
        selectedItem = [searchResults objectAtIndex:indexPath.row];
    } else {
        selectedItem = [fruitsList objectAtIndex:indexPath.row];
    }
    DestinationViewController *destination = segue.destinationViewController;
    destination.fruit = selectedItem;
}

Where fruitsList is an array with all the fruit objects (The one used to show the fruits without any filter), and DestinationViewController is the the controller that will show the picture.

Upvotes: 5

Mundi
Mundi

Reputation: 80271

First, why is your entity name in the plural? That is confusing. You should rename your entity Fruit.

Second, how come your variable names start with capital letters? This is again confusing because they can be mistaken for class names. You should rename your variables fruit, such as in fruit.name.

Third, you should use a NSFetchedResultsController to populate your table view. You could have a separate one just for the search or filter in memory. Both are preferable to doing a manual fetch in each call to filterContentForSearchText. Your filter code looks fine (it is the in-memory version). However, I do not see where you reload the data of your search results table view.

Fourth, the search is completely unrelated to the segue problem. Each cell should be associated with a particular Fruit instance. (Either custom cells with a @property of type Fruit, or use the fetched results controller objectAtIndexPath.) In prepareForSegue you just assign that fruit to the detail view controller (which should have an appropriate @property set up).

Upvotes: 2

Related Questions