Reputation:
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
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