My filteredContentForSearchText ignores predicate after user presses cancel on search bar in iOS.
I am filtering an array with a uisearchbar with the following method:
#pragma mark Content Filtering
-(void)filterContentForSearchText:(NSString*)searchText scope:(NSString*)scope {
[self.filteredUsersArray removeAllObjects];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"SELF.fullName contains[c] %#",searchText];
self.filteredUsersArray = [NSMutableArray arrayWithArray:[self.usersArray filteredArrayUsingPredicate:predicate]];
if ([self.filteredUsersArray count] > 0) {
}else{
User *tempUser = self.addedUsersArray[0];
tempUser.fullName = [NSString stringWithFormat:#"Search for '%#'", searchText];
[self.filteredUsersArray addObject:tempUser];
}
}
Everything works perfect until a user presses cancel or clears there search. After that action occurs this line no longer matches and populates the array:
self.filteredUsersArray = [NSMutableArray arrayWithArray:[self.usersArray filteredArrayUsingPredicate:predicate]];
Does anyone know why the array would return a count of zero after cancel is pressed even when the criteria matches?
Related
To test out a restaurant searching app I included 4 test restaurants in a JSON file which populate a table view correctly with their corresponding properties. In 3 text fields I filter the array with a name, average entree price and rating, yet when I pass it to the method the filtered array logged is not filtered. I don't see anything wrong with my predicate code though, any ideas? Thank you!
- (void)searchRestaurantsWithName:(NSString *)name price:(int)price andRating:(int)rating completion:(void (^)(NSArray *restaurants))completion {
NSMutableArray *restaurantsToFilter = [[RestaurantController sharedInstance].restaurants mutableCopy];
NSPredicate *namePredicate = [NSPredicate predicateWithFormat:#"name CONTAINS[c] %#", name];
NSPredicate *pricePredicate = [NSPredicate predicateWithFormat:#"price < %i", price];
NSPredicate *ratingPredicate = [NSPredicate predicateWithFormat:#"rating > %i", rating];
NSPredicate *compoundPredicate = [NSCompoundPredicate orPredicateWithSubpredicates:#[namePredicate, pricePredicate, ratingPredicate]];
NSArray *filteredArray = [restaurantsToFilter filteredArrayUsingPredicate:compoundPredicate];
completion(filteredArray);
}
The method the button calls
- (void)filterArray {
[self searchRestaurantsWithName:self.nameTextField.text price:[self.priceTextField.text intValue] andRating:[self.ratingTextField.text intValue] completion:^(NSArray *restaurants) {
[self.tableView reloadData];
NSLog(#"%#", restaurants);
}];
}
Actually am getting datas from JSON webservice. I need to search data from UITableView cells using uisearchdisplaycontroller.
I have passed data into cells successfully using NSMutablArray with multiple array. But now i need to search data from that.
My array:
[
{
"name": "jhon",
"city": "chennai",
}
{
"name": "Micle",
"city": "Newyork",
}
{
"name": "Micle",
"city": "Washigton",
}
]
My custom cells in UITableView:
cell.P_name.text = [details objectForKey:#"name"];
cell.P_city.text = [details objectForKey:#"city"];
In Search i tried :
- (void)filterContentForSearchText:(NSString*)searchText scope:(NSString*)scope
{
//-- Help to customize operations
searchResults = [[NSArray alloc]initWithArray:mainArray];
NSPredicate *resultPredicate = [NSPredicate predicateWithFormat:#"SELF contains[cd] %#", searchText];
searchResults = [details filteredArrayUsingPredicate:resultPredicate];
[tableView reloadData];
}
Can anybody help to resolve my issue.
You should have 2 arrays:
Your main store of data from your JSON (mainDataList)
Your data source array used to populate your table view(s) (dataSourceList)
Initially:
self.dataSourceList = self.mainDataList;
because you are displaying all of the data in your table view. When any search is cancelled you also go back to this state (then reload).
When searching however, you need to filter the contents of the dataSourceList and reload the table:
- (void)filterContentForSearchText:(NSString*)searchText scope:(NSString*)scope
{
NSPredicate *resultPredicate = [NSPredicate predicateWithFormat:#"name contains[cd] %#", searchText];
self.dataSourceList = [self.mainDataList filteredArrayUsingPredicate:resultPredicate];
[tableView reloadData];
}
NOTE: the above predicate only searches the name in your dictionaries...
Now, all of your table view methods only use self.dataSourceList, and you modify its contents based on your state. You code is clean and simple. Smile :-)
I just put my logic take one more mutable array in .h file name is _temArray
And add your _mainArray (populated on tableView) to your _temArray such like,
[_temArray addObjectsFromArray:_mainArray];
In Search method use NSPredicate:
- (void)filterContentForSearchText:(NSString*)searchText scope:(NSString*)scope
{
//-- Help to customize operations
if([searchText length] > 0)
{
NSMutableArray *fileterMainArray = (NSMutableArray *)_temArray
NSPredicate *predicatePeople = [NSPredicate predicateWithFormat:#"name BEGINSWITH[cd] %#", searchText]; // here if you want to search by city then change "name" to "city" at pattern.
NSArray *filteredArray = [fileterMainArray filteredArrayUsingPredicate:predicatePeople];
[_mainArray addObjectsFromArray:filteredArray];
}
else
[_mainArray addObjectsFromArray:_temArray];
[self.tblView reloadData]; // don't forget to reload Table data.
}
So I have a group of friends testing my app, and the one person on an iPhone 4 says that the app crashes when he presses the "Go" button attached to my PickerView.
A bit of background: A user selects values in the PickerView, and then presses "Go". Once "Go" is pressed, it searches the database for the user's selected values, and displays results in a TableView.
That said, it works for the other two friends (on a 4S and an iPhone 5). Does anyone know why this might be? See code (point of the crash) below.
pickerviewcontroller.m
- (IBAction)buttonpressed:(UIButton *)sender {
NSLog(#"Button Pushed!");
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
// Make sure your segue name in storyboard is the same as this line
if ([[segue identifier] isEqualToString:#"pickerGo"])
{
NSLog(#"%#", Strains);
// Get reference to the destination view controller
PickerResultsTableViewController *PickerTableView = [segue destinationViewController];
NSLog(#"%#", PickerTableView);
NSPredicate *ailmentPredicate = [NSPredicate predicateWithFormat:#"Ailment CONTAINS[c] %#", [array1 objectAtIndex:[pickerView selectedRowInComponent:0]]];
NSPredicate *actionPredicate = [NSPredicate predicateWithFormat:#"Action CONTAINS[c] %#", [array2 objectAtIndex:[pickerView selectedRowInComponent:1]]];
NSPredicate *ingestPredicate = [NSPredicate predicateWithFormat:#"Ingestion CONTAINS[c] %#", [array3 objectAtIndex:[pickerView selectedRowInComponent:2]]];
NSCompoundPredicate *resultPredicate = [NSCompoundPredicate andPredicateWithSubpredicates:[NSArray arrayWithObjects: ailmentPredicate,actionPredicate,ingestPredicate, nil]];
searchResults = [Strains filteredArrayUsingPredicate:resultPredicate];
// Pass any objects to the view controller here, like...
[PickerTableView setSearchResults: [searchResults copy]];
NSLog(#"%#", searchResults);
}
}
I'm using UISearchBar in my app.
- (void)filterContentForSearchText:(NSString*)searchText scope:(NSString*)scope
{
[self.filtered removeAllObjects];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"SELF.companyName contains[cd] %#",searchText];
NSArray *tempArray = [ee filteredArrayUsingPredicate:predicate];
filtered = [NSMutableArray arrayWithArray:tempArray];
}
I did NSLog on above "filtered" array, it's getting proper search results.
I don't see the filtered values in the tableview. I see "No results" if I type wrong search text. But for the correct search text, the table view is plain empty.
Can anyone help me what needs to be done?
Thanks in advance!!
Please use the following code . And make sure that self.filtered is the datasource of yourtableview . Datasource means array
from tableview gets populated
- (void)filterContentForSearchText:(NSString*)searchText scope:(NSString*)scope
{
[self.filtered removeAllObjects];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"SELF.companyName contains[cd] %#",searchText];
NSArray *tempArray = [ee filteredArrayUsingPredicate:predicate];
filtered = [NSMutableArray arrayWithArray:tempArray];
[yourtableview reloadData];
}
Write the above code then Reload the table in the source code
[tableView reloadData];
I have some arrays whose contents are picked from db.I want to match up the text i have entered in 'searchTextField' with those array's contents which is taken from DB.
For example: my array contains, myArray={'bat man','bat and ball','ball'};
if i have entered 'bat' in 'searchTextField'; it must show index of matching text in array(in this case index 0 and 1).
How can i achieve this..
Waiting for your help..
NSMutableArray *tempArray = [NSMutableArray arrayWithObjects:#"bat man",#"bat and ball",#"ball", nil];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"SELF contains[c] 'bat'"];
NSArray *result = [tempArray filteredArrayUsingPredicate:predicate];
result array will be containing the filtered objects, from there you can get the index as:
[tempArray indexOfObject:/the object from result array, one by one/]
contains[c] means search will be case insensitive. For more on predicates: https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/Predicates/Articles/pUsing.html
EDIT
set the textField's delegate as self. Before that go to YourFile.h, there add UITextFieldDelegate. now in textFieldShouldReturn do this:
- (BOOL)textFieldShouldReturn:(UITextField *)textField {
[textField resignFirstResponder];
NSMutableArray *tempArray = [NSMutableArray arrayWithObjects:#"bat man",#"bat and ball",#"ball", nil];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"SELF contains[c] %#",textField.text];
NSArray *result = [tempArray filteredArrayUsingPredicate:predicate];
return YES;
}