6

I want to create searchBar for my table in storyboard xcode, everythings works for me and I don't have any error, just search doesn't work.

I saw this two tutorial but still doesn't work. I cann't search. my tutorial:

   -http://stackoverflow.com/questions/9897171/uisearchbar-implemented-with-storyboards
   -http://www.youtube.com/watch?v=IqDZHgI_s24

would you please help me, Thanks in Advance!

Here is my code

CreateViewController.h

#import <UIKit/UIKit.h>

@interface CreateViewController : UITableViewController <UITableViewDelegate, UITableViewDataSource,       UISearchBarDelegate>
{
// @property (weak, nonatomic) IBOutlet UISearchBar *searchBar;
NSArray *datas;
NSMutableArray *displayItems;
IBOutlet UITableView * tableView;
IBOutlet UISearchBar * searchbar;
}

@end

CreateViewController.m

#import "CreateViewController.h"

@interface CreateViewController ()

@end

@implementation CreateViewController

- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
    // Custom initialization
}
return self;
}

- (void)viewDidLoad
{
[super viewDidLoad];

datas = [NSMutableArray arrayWithObjects:@"Johan", @"Paul",@"George",@"Ringo", nil];
displayItems = [[NSMutableArray alloc] initWithArray:datas];
[super viewDidLoad];
}

- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}

#pragma mark - Table view data source

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return 1;
}

 - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
return [datas count];
}

- (UITableViewCell *)tableView:(UITableView *)atableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"Cell";//This is the identifier in storyboard    
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if(!cell) {
    cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"Cell"];
}

cell.textLabel.text = [datas objectAtIndex:indexPath.row];
return cell;
}
-(void)searchbar:(UISearchBar *)searchbar textDidChange:(NSString *)searchText{
if([searchText length] == 0){
    [displayItems removeAllObjects];
    [displayItems addObjectsFromArray:datas];
}else{
    [displayItems removeAllObjects];
    for(NSString * string in datas){
        NSRange r = [string rangeOfString:searchText options:NSCaseInsensitiveSearch];
        if (r.location != NSNotFound){
            [displayItems addObject:string];   
        }
    }
}
[tableView reloadData];
}

 #pragma mark - Table view delegate

 - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
 {
// Navigation logic may go here. Create and push another view controller.
/*
 <#DetailViewController#> *detailViewController = [[<#DetailViewController#> alloc] initWithNibName:@"<#Nib    name#>" bundle:nil];
 // ...
 // Pass the selected object to the new view controller.
 [self.navigationController pushViewController:detailViewController animated:YES];
 */
}

@end
Adrian P
  • 6,479
  • 4
  • 38
  • 55

5 Answers5

8

Use this tutorial iOS Quick Tip: Filtering a UITableView with a search bar

http://code-ninja.org/blog/2012/01/08/ios-quick-tip-filtering-a-uitableview-with-a-search-bar/

-(void)searchBar:(UISearchBar*)searchBar textDidChange:(NSString*)text
{
if(text.length == 0)
{
    isFiltered = FALSE;
}
else
{
    isFiltered = true;
    filteredTableData = [[NSMutableArray alloc] init];

    for (Food* food in allTableData)
    {
        NSRange nameRange = [food.name rangeOfString:text options:NSCaseInsensitiveSearch];
        NSRange descriptionRange = [food.description rangeOfString:text options:NSCaseInsensitiveSearch];
        if(nameRange.location != NSNotFound || descriptionRange.location != NSNotFound)
        {
            [filteredTableData addObject:food];
        }
    }
}

[self.tableView reloadData];
}
Elnaz
  • 1,095
  • 1
  • 12
  • 30
  • What if you have sections in your tableview? How can search work knowing that you'll be searching inside the contents of the sections instead of a single array? – jaytrixz Nov 14 '12 at 09:45
  • jaytrixz, you might find my other tutorial on filtering a grouped UITableView useful. It uses a dictionary of arrays instead of a single array. http://code-ninja.org/blog/2012/07/04/filtering-a-grouped-uitableview-with-a-search-bar/ – Marty Nov 30 '12 at 17:52
1

you can use NSPredicate for this function, modify your search delegate method as below

    [datas release];
datas = nil;

datas = [[NSMutableArray alloc] initWithArray: displayItems];
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF like[c] %@",[NSString stringWithFormat:@"%@*",searchBar.text]];
[datas filterUsingPredicate:predicate];
[tableView reloadData];

check the sample code here

http://dl.dropbox.com/u/58723521/SearchSample.zip

vishy
  • 3,241
  • 1
  • 20
  • 25
1

I agree, you need to change your cellForRowAtIndexPath and numberOfRowsInSection to use the displayItems array rather than the datas array. Also check if you have set the UISearchBarDelegate for your search bar.

Charles Menguy
  • 40,830
  • 17
  • 95
  • 117
Nameet
  • 650
  • 8
  • 20
0

Do it like this,

  • In your header file declare arrays like this,

    NSMutableArray *datas;
    NSMutableArray *displayItems;
    
  • Then change array initializing in viewDidLoad like this,

    datas = [[NSMutableArray alloc] initWithObjects:@"Johan", @"Paul",@"George",@"Ringo", nil];
    displayItems = [[NSMutableArray alloc] initWithArray:datas];
    
  • Change the array in cellForRowAt method,

    cell.textLabel.text = [displayItems objectAtIndex:indexPath.row];
    
  • Then print your search string inside textDidChange method using NSLog. If it is not printing, there's something wrong with the IBOutlet connection. If it prints, replace this method and see if it works,

    -(void)searchbar:(UISearchBar *)searchbar textDidChange:(NSString *)searchText{
    
    if([searchText length] == 0){
    
    }else{
        [displayItems removeAllObjects];
        for (int i=0; i<[datas count]; i++) {
            if ([searchText hasPrefix:[datas objectAtIndex:i]]) {
                [displayItems addObject:[datas objectAtIndex:i]];
            } else {
    
            }
        }
    }
    [tableView reloadData];
    }
    

My sorting method is not the best in the world. But try to get your code to work.

Edit: I think your delegate doesn't fire. Try this method instead of the above.

- (void) searchBarSearchButtonClicked:(UISearchBar*) theSearchBar
{
if([searchBar.text length] == 0){
arrayDisplayData = arrayOriginalData;
}else{
    [arrayDisplayData removeAllObjects];
    for(NSString * string in arrayOriginalData){
        NSRange r = [string rangeOfString:searchBar.text options:NSCaseInsensitiveSearch];
        if (r.location != NSNotFound){
            [arrayDisplayData addObject:string];   
        }
    }
}
[tblResults reloadData];
}

Or this,

- (BOOL)searchBar:(UISearchBar *)searchBar shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text
Damitha Raveendra
  • 1,721
  • 17
  • 24
  • Does your tableview shows the data you have put when you start the app?. I mean these, "datas = [NSMutableArray arrayWithObjects:@"Johan", @"Paul",@"George",@"Ringo", nil];" – Damitha Raveendra Apr 26 '12 at 08:59
  • @deamonsarea Thanks, I try it the second one didn't work and in the first one I have error searchBar.text and [tblResults reloadData]; –  Apr 26 '12 at 12:36
0

You need to change you cellForRowAtIndexPath to use the displayItems array rather than the datas array

- (UITableViewCell *)tableView:(UITableView *)atableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"Cell";//This is the identifier in storyboard    
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if(!cell) {
    cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"Cell"];

}

cell.textLabel.text = [displayItems objectAtIndex:indexPath.row];
return cell;
}

And also change the numberOfRowsInSection to use the displayItems array count

 - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{

// Return the number of rows in the section.
return [displayItems count];
}
Craig Mellon
  • 5,399
  • 2
  • 20
  • 25