In this post I will be creating a Search screen, which will have a table view with a search bar. Table should display all the records if search field is empty other wise it should show all the records that have matching strings with the search field.
@interface MySearchScreenAppViewController : UIViewController {
UITableView *myTableView;
NSMutableArray *dataSource; //will be storing all the data
NSMutableArray *tableData;//will be storing data that will be displayed in table
NSMutableArray *searchedData;//will be storing data matching with the search string
UISearchBar *sBar;//search bar
}
@property(nonatomic,retain)NSMutableArray *dataSource;
@end
- (void)loadView {
[super loadView];
sBar = [[UISearchBar alloc]initWithFrame:CGRectMake(0,0,320,30)];
sBar.delegate = self;
[self.view addSubview:sBar];
myTableView = [[UITableView alloc]initWithFrame:CGRectMake(0, 31, 300, 400)];
myTableView.delegate = self;
myTableView.dataSource = self;
[self.view addSubview:myTableView];
//initialize the two arrays; dataSource will be initialized and populated by appDelegate
searchedData = [[NSMutableArray alloc]init];
tableData = [[NSMutableArray alloc]init];
[tableData addObjectsFromArray:dataSource];//on launch it should display all the records
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
//NSLog(@”contacts error in num of row”);
return [tableData count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *MyIdentifier = @”MyIdentifier”;
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:MyIdentifier] autorelease];
}
cell.text = [tableData objectAtIndex:indexPath.row];
return cell;
}
#pragma mark UISearchBarDelegate
- (void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar
{
// only show the status bar’s cancel button while in edit mode
sBar.showsCancelButton = YES;
sBar.autocorrectionType = UITextAutocorrectionTypeNo;
// flush the previous search content
[tableData removeAllObjects];
}
- (void)searchBarTextDidEndEditing:(UISearchBar *)searchBar
{
sBar.showsCancelButton = NO;
}
- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText
{
[tableData removeAllObjects];// remove all data that belongs to previous search
if([searchText isEqualToString:@""]searchText==nil){
[myTableView reloadData];
return;
}
NSInteger counter = 0;
for(NSString *name in dataSource)
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc]init];
NSRange r = [name rangeOfString:searchText];
if(r.location != NSNotFound)
{
if(r.location== 0)//that is we are checking only the start of the names.
{
[tableData addObject:name];
}
}
counter++;
[pool release];
}
[myTableView reloadData];
}
- (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar
{
// if a valid search was entered but the user wanted to cancel, bring back the main list content
[tableData removeAllObjects];
[tableData addObjectsFromArray:dataSource];
@try{
[myTableView reloadData];
}
@catch(NSException *e){
}
[sBar resignFirstResponder];
sBar.text = @”";
}
// called when Search (in our case “Done”) button pressed
- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar
{
[searchBar resignFirstResponder];
}
- (void)applicationDidFinishLaunching:(UIApplication *)application {
// Override point for customization after app launch
viewController.dataSource = [[NSMutableArray alloc]init];
for(char c = ‘A’;c<=‘Z’;c++)
[viewController.dataSource addObject:[NSString stringWithFormat:@"%cTestString",c]];
UINavigationController *nvc = [[UINavigationController alloc]initWithRootViewController:viewController];
viewController.title = @”Search”;
[window addSubview:nvc.view];
[window makeKeyAndVisible];
- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText
{
[tableData removeAllObjects];// remove all data that belongs to previous search
if([searchText isEqualToString:@""]searchText==nil){
[myTableView reloadData];
return;
}
NSInteger counter = 0;
for(NSString *name in dataSource)
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc]init];
NSRange r = [name rangeOfString:searchText];
if(r.location != NSNotFound)
[tableData addObject:name];
counter++;
[pool release];
}
[myTableView reloadData];
}



[...] Implementing a search bar in the table [...]
how would you search an xml array brought in using the NSXML parser?
Could you please provide a little more detail as in what you are trying to do?
This literally Fucked up my entire project! Now I have 22 errors and I don’t know why!
Look for a missing semicolon ..it sometimes triggers 500+ errors in my code ..lol
any ways..look through your code, you must have done something wrong..
Thanks a lot. It works but there are just few syntactic in it..
I have made the few changes in it..
- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText
{
[tableData removeAllObjects];// remove all data that belongs to previous search
if([searchText isEqualToString:@""] || searchText==nil)
{
[myTableView reloadData];
return;
}
NSInteger counter = 0;
for(NSString *name in dataSource)
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc]init];
NSRange r = [name rangeOfString:searchText];
if(r.location != NSNotFound)
{
if(r.location== 0)//that is we are checking only the start of the names.
{
[tableData addObject:name];
}
}
counter++;
[pool release];
}
[myTableView reloadData];
}
Thanks Harinder, can u plz let me know the place where u found d issue..i usually paste the code from my working code only.
i have tried several of these and i get 30-40 errors each time
i have no idea what i am doing wrong
i follow it step by step
paste your code here so that we can debug it,,
Nice tutorial, however when I build and run the app it quits due to an uncaught exception. I have several warnings in the code that I’m not sure what they mean:
http://img18.imageshack.us/img18/5504/warningsc.jpg
Do you know what’s causing this and how to fix them? Thanks.
Hi,
Seems very useful. I’m running xCode version 3.1.3 and I am receiving close to 30 compilation errors.
loadView compiled full of errors. Could you supply us with your working xCode project as it appears that a few people who posted here are having compile problems.
@ iPhoneDev: Yes you have to write a piece of code like this in your header file
@interface DataSet : UITableViewController {
//rest of the code goes here
}
And implement the UITableViewDelegate, UITableViewDataSource, UISearchBarDelegate classes
i have the same warning messages as iPhoneDev encountered above, and the app quite unexpectedly in simulator.
I realized that my code examples have some compatibility issues with 3.0, will fix em soon and upload the source files
Hi ABC,
You havent used searchedData at all. I guess u should be using searchedData instead of tableData array in the Search Delegate.
I have some issues with your tutorials as well. I’m running Xcode 3.2.1. Maybe you’re right about the compatibility.
the code is working but i am not getting the list of contents wwhen i clear the search bar. And also error occurs coz of redefinition of
- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText
how to make search case insensitive?
Obviously, the view controller should implement several delegate protocols for the things to work, so the declaration should look like this:
@interface MySearchScreenAppViewController : UIViewController
Obviously, the view controller should implement several delegate protocols for the things to work, so the declaration should look like this:
@interface MySearchScreenAppViewController : UIViewController < UISearchBarDelegate, UITableViewDelegate, UITableViewDataSource >
Hello everybody, can somebody send this code in xCode files? Because it’s a lot of mistakes. Maybe i don’t understand something. I very need this example. Thanks a lot.
ABC thanks for the code. Works great.
You do have a typo though on this line:
if([searchText isEqualToString:@""]searchText==nil)
It should be this:
if([searchText isEqualToString:@""] || searchText==nil)
Also, searchedData is never used so can be removed.
Thanks!
Seems to be causing a lot of people confusion.
Thanks for the code ABC. Kudos on being patient with the people who commented!