I am having UISearchBar above UITableView. Its not filtering the data
Here is my code
- (void)searchBar:(UISearchBar*)searchBar textDidChange:(NSString*)text {
if (text) {
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"SELF contains[c] %#", text];
_filteredDataArray = [_dataArray filteredArrayUsingPredicate:predicate];
}
[_tableView reloadData];
}
dataArray is an NSMutableArray and filteredDataArray is an NSArray. I've tried the solutions which are given already but its not working that's why am asked again... What I am doing wrong
TRY THIS CODE FOR SEARCH FILTER:
- (void)searchBar:(UISearchBar*)searchBar textDidChange:(NSString*)text {
if (text) {
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"SELF CONTAINS[cd] %#", text];
_filteredDataArray = [_dataArray filteredArrayUsingPredicate:predicate];
}
[_tableView reloadData];
}
i guess u need to see this, try this function it works for me, but its in swift 3.0, hope it helps you too.
func searchFromList(searchText:String, mainArray:AnyObject, key:String) -> AnyObject{
var searchArray:[AnyObject]
searchArray = []
if searchText.length > 0 {
if mainArray.count > 0 {
let predicate = NSPredicate(format: "\(key) contains[c] %#", searchText)
searchArray = mainArray.filteredArrayUsingPredicate(predicate)
}
}
return searchArray
}
Related
Below is my model class
{"ID":1,"Name":"Area 1","Code":"xyz","StartTime":"09:30","EndTime":"13:40"},
{"ID":2,"Name":"Area 2","Code":"xyz","StartTime":"09:00","EndTime":"13:40"},
{"ID":3,"Name":"Area 3","Code":"xyz","StartTime":"10:30","EndTime":"14:40"},
{"ID":4,"Name":"Area 4","Code":null,"StartTime":"09:30","EndTime":"13:30"}]
I have retrieved model class value in NSMutableArray and displayed on TableView, Now I need to search name from model class, Below is my code, however its not been working.
-(void)updateSearchResultsForSearchController:(UISearchController *)searchController {
NSString *searchString = searchController.searchBar.text;
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"SELF CONTAINS [cd] %#", searchString];
for (NSString *key in _arrAlreaList) {
NSArray *array = [_arrAlreaList valueForKey:key];
NSArray *tempArray = [array filteredArrayUsingPredicate:predicate];
if (tempArray.count > 0) {
[filteredArray addObjectsFromArray:tempArray];
[self.tblArea reloadData];
}
}
}
-(void)updateSearchResultsForSearchController:(UISearchController *)searchController {
NSString *searchString = searchController.searchBar.text;
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"SELF.Name contains [c] %#", searchString];
NSArray *resultArray = [_arrAlreaList filteredArrayUsingPredicate:predicate];
NSLog(#"Result Array %#",resultArray);
}
Try This !!
- (void)filterContentForSearchText:(NSString*)searchText scope:(NSString*)scope {
if ([searchText hasPrefix:#"#"]) {
NSPredicate *resultPredicate = [NSPredicate predicateWithFormat:#"(def contains[c] %#)", searchText];
searchResults = [chengduhua filteredArrayUsingPredicate:resultPredicate];
} else {
NSPredicate *resultPredicate = [NSPredicate predicateWithFormat:#"(head beginswith[c] %#) OR (pro beginswith[c] %#) OR (searchableStringValue beginswith[c] %#)", searchText, searchText, searchText];
searchResults = [chengduhua filteredArrayUsingPredicate:resultPredicate];
}
}
My else is working fine, but any # prefixed searches turn up empty.
Any hints?
Is searchText the right thing I need to be prefixing?!
Here's my search display controller:
-(BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString
{
[self filterContentForSearchText:searchString
scope:[[self.searchDisplayController.searchBar scopeButtonTitles]
objectAtIndex:[self.searchDisplayController.searchBar
selectedScopeButtonIndex]]];
return YES;
}
You might find this fixes it :
NSPredicate *resultPredicate = [NSPredicate predicateWithFormat:#"(def contains[c] '%#')", searchText];
(Note the addition of quotation marks around the %#)
Didn't strip the stupid prefix.
Here's my solution
NSString *prefixToRemove =#"#";
NSString *newString = [searchText copy];
if ([searchText hasPrefix:prefixToRemove])
newString = [searchText substringFromIndex:[prefixToRemove length]];
NSPredicate *resultPredicate = [NSPredicate predicateWithFormat:#"(def contains[c] %#)", newString];
I created a "invite friends" feature for a iOS app I'm building. I was able to add alphabetical sections A-Z, by iterating through the large array, using NSPredicate picking out all names that start with A then B all the way to Z. Saving them into a dictionary were the keys are A-Z.
Everything works, but opening that view takes about 7 seconds from the moment I click the "invite friends" button.
What can I do to make this load seamlessly or atleast make it seem seamless to the users and improving the design and my code?
Here is my code
-(void)testing {
NSMutableArray *stringName = [[NSMutableArray alloc] init];
for (NSDictionary* item in self.tableData) {
// self.user = item;
NSString* firstName = [item objectForKey:#"firstName"];
[stringName addObject:firstName];
NSPredicate *aPredicate = [NSPredicate predicateWithFormat:#"SELF beginswith[c] 'A'"];
NSArray *beginWithA = [stringName filteredArrayUsingPredicate:aPredicate];
NSPredicate *bPredicate = [NSPredicate predicateWithFormat:#"SELF beginswith[c] 'B'"];
NSArray *beginWithB = [stringName filteredArrayUsingPredicate:bPredicate];
NSPredicate *cPredicate = [NSPredicate predicateWithFormat:#"SELF beginswith[c] 'C'"];
NSArray *beginWithC = [stringName filteredArrayUsingPredicate:cPredicate];
NSPredicate *dPredicate = [NSPredicate predicateWithFormat:#"SELF beginswith[c] 'D'"];
NSArray *beginWithD = [stringName filteredArrayUsingPredicate:dPredicate];
NSPredicate *ePredicate = [NSPredicate predicateWithFormat:#"SELF beginswith[c] 'E'"];
NSArray *beginWithE = [stringName filteredArrayUsingPredicate:ePredicate];
NSPredicate *fPredicate = [NSPredicate predicateWithFormat:#"SELF beginswith[c] 'F'"];
NSArray *beginWithF = [stringName filteredArrayUsingPredicate:fPredicate];
NSPredicate *gPredicate = [NSPredicate predicateWithFormat:#"SELF beginswith[c] 'G'"];
NSArray *beginWithG = [stringName filteredArrayUsingPredicate:gPredicate];
NSPredicate *hPredicate = [NSPredicate predicateWithFormat:#"SELF beginswith[c] 'H'"];
NSArray *beginWithH = [stringName filteredArrayUsingPredicate:hPredicate];
NSPredicate *iPredicate = [NSPredicate predicateWithFormat:#"SELF beginswith[c] 'I'"];
NSArray *beginWithI = [stringName filteredArrayUsingPredicate:iPredicate];
NSPredicate *jPredicate = [NSPredicate predicateWithFormat:#"SELF beginswith[c] 'J'"];
NSArray *beginWithJ = [stringName filteredArrayUsingPredicate:jPredicate];
NSPredicate *kPredicate = [NSPredicate predicateWithFormat:#"SELF beginswith[c] 'K'"];
NSArray *beginWithK = [stringName filteredArrayUsingPredicate:kPredicate];
NSPredicate *lPredicate = [NSPredicate predicateWithFormat:#"SELF beginswith[c] 'L'"];
NSArray *beginWithL = [stringName filteredArrayUsingPredicate:lPredicate];
NSPredicate *mPredicate = [NSPredicate predicateWithFormat:#"SELF beginswith[c] 'M'"];
NSArray *beginWithM = [stringName filteredArrayUsingPredicate:mPredicate];
NSPredicate *nPredicate = [NSPredicate predicateWithFormat:#"SELF beginswith[c] 'N'"];
NSArray *beginWithN = [stringName filteredArrayUsingPredicate:nPredicate];
NSPredicate *oPredicate = [NSPredicate predicateWithFormat:#"SELF beginswith[c] 'O'"];
NSArray *beginWithO = [stringName filteredArrayUsingPredicate:oPredicate];
NSPredicate *pPredicate = [NSPredicate predicateWithFormat:#"SELF beginswith[c] 'P'"];
NSArray *beginWithP = [stringName filteredArrayUsingPredicate:pPredicate];
NSPredicate *qPredicate = [NSPredicate predicateWithFormat:#"SELF beginswith[c] 'Q'"];
NSArray *beginWithQ = [stringName filteredArrayUsingPredicate:qPredicate];
NSPredicate *rPredicate = [NSPredicate predicateWithFormat:#"SELF beginswith[c] 'R'"];
NSArray *beginWithR = [stringName filteredArrayUsingPredicate:rPredicate];
NSPredicate *sPredicate = [NSPredicate predicateWithFormat:#"SELF beginswith[c] 'S'"];
NSArray *beginWithS = [stringName filteredArrayUsingPredicate:sPredicate];
NSPredicate *tPredicate = [NSPredicate predicateWithFormat:#"SELF beginswith[c] 'T'"];
NSArray *beginWithT = [stringName filteredArrayUsingPredicate:tPredicate];
NSPredicate *uPredicate = [NSPredicate predicateWithFormat:#"SELF beginswith[c] 'U'"];
NSArray *beginWithU = [stringName filteredArrayUsingPredicate:uPredicate];
NSPredicate *vPredicate = [NSPredicate predicateWithFormat:#"SELF beginswith[c] 'V'"];
NSArray *beginWithV = [stringName filteredArrayUsingPredicate:vPredicate];
NSPredicate *wPredicate = [NSPredicate predicateWithFormat:#"SELF beginswith[c] 'W'"];
NSArray *beginWithW = [stringName filteredArrayUsingPredicate:wPredicate];
NSPredicate *xPredicate = [NSPredicate predicateWithFormat:#"SELF beginswith[c] 'X'"];
NSArray *beginWithX = [stringName filteredArrayUsingPredicate:xPredicate];
NSPredicate *yPredicate = [NSPredicate predicateWithFormat:#"SELF beginswith[c] 'Y'"];
NSArray *beginWithY = [stringName filteredArrayUsingPredicate:yPredicate];
NSPredicate *zPredicate = [NSPredicate predicateWithFormat:#"SELF beginswith[c] 'Z'"];
NSArray *beginWithZ = [stringName filteredArrayUsingPredicate:zPredicate];
// Dictionary
self.sectionDict = [[NSMutableDictionary alloc] init];
if (![beginWithA count] == 0) {
_sectionDict[#"A"] = beginWithA;
}
if (![beginWithB count] == 0) {
_sectionDict[#"B"] = beginWithB;
}
if (![beginWithC count] == 0) {
_sectionDict[#"C"] = beginWithC;
}
if (![beginWithD count] == 0) {
_sectionDict[#"D"] = beginWithD;
}
if (![beginWithE count] == 0) {
_sectionDict[#"E"] = beginWithE;
}
if (![beginWithF count] == 0) {
_sectionDict[#"F"] = beginWithF;
}
if (![beginWithG count] == 0) {
_sectionDict[#"G"] = beginWithG;
}
if (![beginWithH count] == 0) {
_sectionDict[#"H"] = beginWithH;
}
if (![beginWithI count] == 0) {
_sectionDict[#"I"] = beginWithI;
}
if (![beginWithJ count] == 0) {
_sectionDict[#"J"] = beginWithJ;
}
if (![beginWithK count] == 0) {
_sectionDict[#"K"] = beginWithK;
}
if (![beginWithL count] == 0) {
_sectionDict[#"L"] = beginWithL;
}
if (![beginWithM count] == 0) {
_sectionDict[#"M"] = beginWithM;
}
//
if (![beginWithN count] == 0) {
_sectionDict[#"N"] = beginWithN;
}
if (![beginWithO count] == 0) {
_sectionDict[#"O"] = beginWithO;
}
if (![beginWithP count] == 0) {
_sectionDict[#"P"] = beginWithP;
}
if (![beginWithQ count] == 0) {
_sectionDict[#"Q"] = beginWithQ;
}
if (![beginWithR count] == 0) {
_sectionDict[#"R"] = beginWithR;
}
if (![beginWithS count] == 0) {
_sectionDict[#"S"] = beginWithS;
}
if (![beginWithT count] == 0) {
_sectionDict[#"T"] = beginWithT;
}
if (![beginWithU count] == 0) {
_sectionDict[#"U"] = beginWithU;
}
if (![beginWithV count] == 0) {
_sectionDict[#"V"] = beginWithV;
}
if (![beginWithW count] == 0) {
_sectionDict[#"W"] = beginWithW;
}
if (![beginWithX count] == 0) {
_sectionDict[#"X"] = beginWithX;
}
if (![beginWithY count] == 0) {
_sectionDict[#"Y"] = beginWithY;
}
if (![beginWithZ count] == 0) {
_sectionDict[#"Z"] = beginWithZ;
}
}
self.dictSectionTitles = [[self.sectionDict allKeys] sortedArrayUsingSelector:#selector(localizedCaseInsensitiveCompare:)];
}
Here is the other in which I call the method.
-(void)viewWillAppear:(BOOL)animated {
[self loadData];
}
- (void)loadData
{
[self.contactsManager importContacts:^(NSArray *contacts)
{
self.tableData = contacts;
[self testing];
[self.tableView reloadData];
NSLog(#"contacts: %#",contacts);
}];
}
Thanks!
You are essentially traversing the entire array 26 times. You need an algorithm that only traverses once, building up your dictionary as you go along.
NSMutableDictionary *sectionDict = [NSMutableDictionary dictionary];
for (NSString *s in array) {
NSString *firstLetter = [s substringToIndex:1];
NSMutableArray *section = sectionDict[firstLetter];
if (section == nil) {
section = [NSMutableArray array];
sectionDict[firstLetter] = section;
}
section addObject:s];
}
I have the following extension method to search in an array:
- (NSArray *)searchItemsForTerm:(NSString *)term;
{
NSPredicate *resultPredicate = [NSPredicate predicateWithFormat:#"name contains[c] %#", term];
return [[self filteredArrayUsingPredicate:resultPredicate] copy];
}
Sometimes not all my objects in the array have the "name" property. In this case I get an exception.
Is there a way to create this predicate which can ignore any non existing properties?
Thanks!
Something like:
- (NSArray *)searchItemsForTerm:(NSString *)term;
{
NSPredicate *resultPredicate = [NSPredicate predicateWithFormat:#"name contains[c] %#", term];
NSArray *filteredArray = [self filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(id evaluatedObject, NSDictionary *bindings) {
if ([evaluatedObject respondsToSelector:#selector(name)]) {
return [resultPredicate evaluateWithObject:evaluatedObject];
}
return NO;
}]];
return filteredArray;
}
I have a tableview with a search bar. I was able to use NSPredicate to search the tableview when I add the items to another array:
for(head in items){
[desc addObject:head.DESC];
[category addObject:head.CATEGORY];
}
- (void)filterContentForSearchText:(NSString*)searchText scope:(NSString*)scope
{
NSPredicate *resultPredicate = [NSPredicate predicateWithFormat:#"self CONTAINS[cd] %#", searchText];
searchResults = [desc filteredArrayUsingPredicate:resultPredicate];
}
Now I want to keep the collection together so that a tableView didSelectRowAtIndexPath will be able to use the category object.
I load my table view like this:
for (int i = 0; i < [items count]; i++){
head = [items objectAtIndex:indexPath.row];
labelName.text = head.DESC;
How can I get my NSPredicate to search the collection for head.DESC?
#pragma mark Search Results
- (void)filterContentForSearchText:(NSString*)searchText scope:(NSString*)scope
{
NSPredicate *resultPredicate = [NSPredicate predicateWithFormat:#"self CONTAINS[cd] %#", searchText];
searchResults = [items filteredArrayUsingPredicate:resultPredicate];
}
Currently, I am getting this exception when running the above code.
reason: 'Can't use in/contains operator with collection <Order: 0x7b22e900> (not a collection)'
I think I understand your question. You want to be able to filter your items array (which is a bunch of heads) by the DESC property. How about using blocks?
- (void)filterContentForSearchText:(NSString*)searchText scope:(NSString*)scope
{
NSPredicate *resultPredicate = [NSPredicate predicateWithBlock:^BOOL(id evaluatedObject, NSDictionary *bindings) {
return [[evaluatedObject DESC] containsString:searchText];
}];
searchResults = [items filteredArrayUsingPredicate:resultPredicate];
}
If your Order object defines DESC as a #property (or is otherwise KVC Compliant), you'll be able to just access it directly. This should work:
- (void)filterContentForSearchText:(NSString*)searchText scope:(NSString*)scope
{
NSPredicate *resultPredicate = [NSPredicate predicateWithFormat:#"self.DESC CONTAINS[cd] %#", searchText];
searchResults = [items filteredArrayUsingPredicate:resultPredicate];
}
I think it helps you:
- (void)filterContentForSearchText:(NSString*)searchText scope:(NSString*)scope
{
NSPredicate *resultPredicate = [NSPredicate predicateWithFormat:#"ANY self.DESC CONTAINS[cd] %#", searchText];
searchResults = [items filteredArrayUsingPredicate:resultPredicate];
}