6

Are there any good tutorials or ways of turning a text field into a search bar?

I already have my search bar set up with search bar + search display controller and it's working alright -- but it's hard to customize...specifically getting rid of the ugly grey overlay and apparently this is the best way to go.

I haven't been able to find any info on doing this and figured someone has have to have done it before.

vikingosegundo
  • 52,040
  • 14
  • 137
  • 178
Mou某
  • 556
  • 3
  • 10
  • 32
  • For Swift 3. I found a solution here: [**Customize textfield easily**](http://stackoverflow.com/a/40105165/4593553) – Jerome Oct 18 '16 at 10:03

2 Answers2

10

i don't know of any tutorials that covers that subject, but sometime ago with help of someone else i was able to accomplish that. here is the total code in .h and .m file. i can explain the whole thing but it is commented on each line so i guess it is clear enough.

.h

#import <UIKit/UIKit.h>

@interface SEMainVC : UIViewController <UITextFieldDelegate>{
    NSMutableArray *dummyArray;
    NSMutableArray *searchArray;
    NSString *searchTextString;
}

@property (weak, nonatomic) IBOutlet UITextField *searchTextField;
@property (weak, nonatomic) IBOutlet UITableView *contentTableView;

- (void) setupData;

@end

.m

@interface SEMainVC ()

@end

@implementation SEMainVC

- (void)viewDidLoad
{
    [super viewDidLoad];
    //set the selector to the text field in order to change its value when edited
    [self.searchTextField addTarget:self action:@selector(textFieldDidChange:) forControlEvents:UIControlEventEditingChanged];
    //here you set up the methods to search array and reloading the tableview
    [self setupData];
    [self updateSearchArray];
    [self.contentTableView reloadData];
}
//setting up the data sourch for the mutable array
- (void) setupData {
    dummyArray = [[NSMutableArray alloc] init];

    [dummyArray addObject:[[NSMutableDictionary alloc] initWithObjectsAndKeys:@"dummy 1", @"name" , @"image1.JPG", @"image" , @"dummy 1 description textview", @"description", nil]];
    [dummyArray addObject:[[NSMutableDictionary alloc] initWithObjectsAndKeys:@"dummy 2", @"name" , @"image1.JPG", @"image" , @"dummy 2 description textview", @"description", nil]];
    [dummyArray addObject:[[NSMutableDictionary alloc] initWithObjectsAndKeys:@"dummy 3", @"name" , @"image1.JPG", @"image" , @"dummy 3 description textview", @"description", nil]];

}
- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
}

#pragma mark - Table view data source

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return [searchArray count];
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *cellIdentifier = @"Cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
    if( cell == nil ){
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
    }
    cell.textLabel.text = [[searchArray objectAtIndex:indexPath.row] objectForKey:@"name"];
    return cell;
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    [self performSegueWithIdentifier:@"DummyDetail" sender:[NSNumber numberWithInt:indexPath.row]];
}

#pragma mark - Search Methods

-(void)textFieldDidChange:(UITextField*)textField
{
    searchTextString = textField.text;
    [self updateSearchArray];
}
//update seach method where the textfield acts as seach bar
-(void)updateSearchArray
{
    if (searchTextString.length != 0) {
        searchArray = [NSMutableArray array];
        for ( NSDictionary* item in dummyArray ) {
            if ([[[item objectForKey:@"name"] lowercaseString] rangeOfString:[searchTextString lowercaseString]].location != NSNotFound) {
                [searchArray addObject:item];
            }
        }
    } else {
        searchArray = dummyArray;
    }

    [self.contentTableView reloadData];
}

#pragma mark - Table view delegate

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(NSNumber*)indexNumber
{
    if([[segue identifier] isEqualToString:@"DummyDetail"]){

        NSInteger index = [indexNumber integerValue];

        SEDetailVC *dummyDetail = [segue destinationViewController];
        dummyDetail.dummyImageString = [[searchArray objectAtIndex:index] objectForKey:@"image"];
        dummyDetail.dummyTextString = [[searchArray objectAtIndex:index] objectForKey:@"description"];
        dummyDetail.title = [[searchArray objectAtIndex:index] objectForKey:@"name"];
    }
}

- (void)viewDidUnload {
    [self setSearchTextField:nil];
    [self setContentTableView:nil];
    [super viewDidUnload];
}
@end

i hope the above is clear and helpful enough, let me know if you need any assistance with it.

Adrian P
  • 6,479
  • 4
  • 38
  • 55
  • Hello @XCode Monkey .I am getting my data from server and displaying in tableview .I have to implement textfield as search bar and search in that textfield .I have tried your code but i'm not getting.Please help me – App Developer Dec 01 '15 at 11:56
  • @AppDeveloper, with ought seeing your code, it is hard to offer assistance. The above code is set for a simple array that its members are declared on the same class. It may be related to the method you are using to extract the data from server. – Adrian P Dec 01 '15 at 23:12
  • - (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string { NSPredicate *predicate = [NSPredicate predicateWithFormat:@"strSubCatName contains[cd] %@",textField.text]; searchArray =[NSMutableArray arrayWithArray:[arrSubCatOb filteredArrayUsingPredicate:predicate]]; NSLog(@"search array is:%@",searchArray); [self.tableViewForSubCat reloadData]; return YES; } – App Developer Dec 02 '15 at 05:25
  • I'm using this code for filtering tableview data using custom search textfield – App Developer Dec 02 '15 at 06:14
3

Download the complete source code from here https://github.com/shashidev/TextFieldAsSearchBar.git

or

#import "ViewController.h"

@interface ViewController()

<UITableViewDataSource,UITableViewDelegate,UITextFieldDelegate>
{
    NSMutableArray *arrOfColor;
    NSMutableArray *searchArray;
    NSString *searchTextString;
    BOOL isFilter;
}

@property (strong, nonatomic) IBOutlet UITextField *searchTextField;
@property (strong, nonatomic) IBOutlet UITableView *colorTableview;

@end

Implement the .m file.

@implementation ViewController

- (void)viewDidLoad 

{
    [super viewDidLoad];
    arrOfColor=[NSMutableArray arrayWithObjects:@"Red",@"Green",@"Blue",@"Gray",@"Black",@"White",@"Yellow",@"Brown",@"Pink",nil];
    [self.searchTextField addTarget:self action:@selector(textFieldDidChange:) forControlEvents:UIControlEventEditingChanged];
}

-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
      return 1;
}

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

    if(isFilter)
    {
        return [searchArray count];
    }
    else
        return  [arrOfColor count];
}

-(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{

    UITableViewCell *cell=[tableView dequeueReusableCellWithIdentifier:@"cell"];
    if(!cell)
    {
        cell=[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"cell"];
    }
    if(isFilter)
    {
        cell.textLabel.text=[searchArray objectAtIndex:indexPath.row];
    }
    else
    {
          cell.textLabel.text=[arrOfColor objectAtIndex:indexPath.row];
    }

    return cell;
}

-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    if(isFilter)
    {
        _searchTextField.text=[searchArray objectAtIndex:indexPath.row];
    }
    else
    {
        _searchTextField.text=[arrOfColor objectAtIndex:indexPath.row];

    }
}

-(void)textFieldDidChange:(UITextField *)textField
{
    searchTextString=textField.text;
    [self updateSearchArray:searchTextString];
}

-(void)updateSearchArray:(NSString *)searchText
{
    if(searchText.length==0)
    {
        isFilter=NO;
   }
   else
   {
        isFilter=YES;
        searchArray=[[NSMutableArray alloc]init];
        for(NSString *string in arrOfColor){

            NSRange stringRange=[string rangeOfString:searchText options:NSCaseInsensitiveSearch];
            if(stringRange.location !=NSNotFound){

                [searchArray addObject:string];
            }
        }
         [self.colorTableview reloadData];}
    }

-(BOOL)textFieldShouldReturn:(UITextField *)textField
{
    [textField resignFirstResponder];
    return YES;
}
@end
Ravi Dhorajiya
  • 1,531
  • 3
  • 21
  • 26
Shashi Dev
  • 31
  • 4
  • your code is perfect but It also update my id of array. It change according to tableview index.Can you assist me. – Muju Oct 13 '16 at 09:29
  • Thank you man only small change instead of for loop I used `NSPredicate` that will be more fast if the array is big. – Mihir Oza Nov 01 '19 at 10:26