user3693546
user3693546

Reputation:

How do I filter this object array using NSPredicate?

How do I filter this object array using NSPredicate filteredArrayUsingPredicate / predicateWithBlock?

Class Person is my modal class that has several properties like firstName, lastName etc. each object of this class is stored in an array objPersonCell. And from my view controller I am displaying fields on UITableViewCell using :

// way similar to this
        for(NSMutableArray *obj in self.objPersonCell){   
            lblFirstName.text = [(Person *)obj personType];
        }

Problem : For Search, I want user to type and filter objPersonCell using NSPredicate and immediately reflect the changes by reloading the data on UITableView. Now how do I use NSPredicate.

What I have tried is :

    - (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
    {
        NSString *searchTerm = [textField.text stringByReplacingCharactersInRange:range withString:string];
        [self updateAsPerSearchTerm: searchTerm];

        return YES;
    }

-(void)updateAsPerSearchTerm:(NSString *)searchTerm
{

    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"self contains[cd] %@",searchTerm];
    NSArray *sortedArray = [[(Person *)self.objPersonCell] filteredArrayUsingPredicate:predicate];

    [self.objPersonCell removeAllObjects];
    [self.objPersonCell addObjectsFromArray:sortedArray];
    [self.tableView reloadData];
}

The code inside updateAsPerSearchTerm is wrong for passing objPersonCell. How do I set it up. And How predicateWithBlock would better help me out, if can ?

Upvotes: 1

Views: 657

Answers (1)

Wain
Wain

Reputation: 119021

You seem to be confused about casting. This code:

for(NSMutableArray *obj in self.objPersonCell){   
    lblFirstName.text = [(Person *)obj personType];
}

should be

for (Person *obj in self.objPersonCell){   
    lblFirstName.text = [obj personType];
}

because the contents of the objPersonCell array are Person objects.

A similar problem is here:

NSArray *sortedArray = [[(Person *)self.objPersonCell] filteredArrayUsingPredicate:predicate];

where you should have

NSArray *sortedArray = [self.objPersonCell filteredArrayUsingPredicate:predicate];

Now, on your filtering problem, you should have a couple of properties:

@property (strong, nonatomic) NSMutableArray *objPersonCell;
@property (strong, nonatomic) NSArray *tableDataSource;

by default:

self.tableDataSource = self.objPersonCell;

when you do a search:

self.tableDataSource = sortedArray;

when you cancel / complete a search:

self.tableDataSource = self.objPersonCell;

In this way you are never editing objPersonCell while searching (and corrupting its contents) and your table data source methods remain simple as you aren't trying to switch between different source arrays. The table data source methods should use only tableDataSource, not objPersonCell.

Upvotes: 1

Related Questions