p2p.wrox.com Forums

p2p.wrox.com Forums (http://p2p.wrox.com/)
-   BOOK: Beginning iPhone SDK Programming with Objective-C (http://p2p.wrox.com/book-beginning-iphone-sdk-programming-objective-c-543/)
-   -   Search Bar (http://p2p.wrox.com/book-beginning-iphone-sdk-programming-objective-c/86962-search-bar.html)

Jule March 14th, 2012 02:20 AM

Search Bar
 
I have a table view app that i would like to have a search bar on, i have tried the search bar in chapter 10 but it does not work, think i have coded it wrong. Can I get help to get this.

there is my rootviewcontroller.m file

Code:



#import "RootViewController.h"
#import "DetailViewController.h"

@implementation RootViewController

#define CELL_HEIGHT 80.0

/*
- (void)viewDidLoad {
    [super viewDidLoad];

    // Uncomment the following line to display an Edit button in the navigation bar for this view controller.
    // self.navigationItem.rightBarButtonItem = self.editButtonItem;
}
*/


- (void)viewWillAppear:(BOOL)animated {
    dao = [[cropLibraryDao alloc] initWithLibraryName:@"TestData"];
    self.title = @"Crop List";
    [self.tableView deselectRowAtIndexPath:[self.tableView indexPathForSelectedRow] animated:YES];
}

/*
- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];
}
*/
/*
- (void)viewWillDisappear:(BOOL)animated {
        [super viewWillDisappear:animated];
}
*/
/*
- (void)viewDidDisappear:(BOOL)animated {
        [super viewDidDisappear:animated];
}
*/


 // Override to allow orientations other than the default portrait orientation.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
        // Return YES for supported orientations.
        return YES; //(interfaceOrientation == UIInterfaceOrientationPortrait);
}


- (void)didReceiveMemoryWarning {
        // Releases the view if it doesn't have a superview.
    [super didReceiveMemoryWarning];
       
        // Release any cached data, images, etc that aren't in use.
}

- (void)viewDidUnload {
        // Release anything that can be recreated in viewDidLoad or on demand.
        // e.g. self.myOutlet = nil;
}


#pragma mark Table view methods

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


// Customize the number of rows in the table view.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return [dao libraryCount];
}


// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
   
    static NSString *CellIdentifier = @"LibraryListingCell";
   
    cropListingViewCell *cell = (cropListingViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        [[NSBundle mainBundle] loadNibNamed:@"cropListingView" owner:self options:nil];
        cell = [_cell autorelease];
        _cell = nil;
    }
   
        cell.nameLabel.text = [[dao libraryItemAtIndex:indexPath.row] valueForKey:@"name"];   
    cell.levelLabel.text = [NSString stringWithFormat:@"Level %@ ",
                                    [[dao libraryItemAtIndex:indexPath.row] valueForKey:@"level"]];
    cell.cropImageView.image = [UIImage
                                imageNamed:[[dao libraryItemAtIndex:indexPath.row] valueForKey:@"cropImage"]];

    return cell;
}



// Override to support row selection in the table view.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    DetailViewController *controller = [[DetailViewController alloc]
                                        initWithcropData:[dao libraryItemAtIndex:indexPath.row]
                                        nibName:@"DetailViewController" bundle:[NSBundle mainBundle]];
    controller.title = [[dao libraryItemAtIndex:indexPath.row] valueForKey:@"name"];
    [self.navigationController pushViewController:controller animated:YES];
    [controller release];   
}


- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
    return CELL_HEIGHT;
}

/*
// Override to support conditional editing of the table view.
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
    // Return NO if you do not want the specified item to be editable.
    return YES;
}
*/


/*
// Override to support editing the table view.
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
   
    if (editingStyle == UITableViewCellEditingStyleDelete) {
        // Delete the row from the data source.
        [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
    } 
    else if (editingStyle == UITableViewCellEditingStyleInsert) {
        // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view.
    } 
}
*/


/*
// Override to support rearranging the table view.
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath {
}
*/


/*
// Override to support conditional rearranging of the table view.
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath {
    // Return NO if you do not want the item to be re-orderable.
    return YES;
}
*/


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


@end

and rootviewcontroller.h
Code:

#import "cropLibraryDao.h"
#import "cropListingViewCell.h"

@interface RootViewController : UITableViewController {
    cropLibraryDao *dao;
   
    IBOutlet cropListingViewCell *_cell;
}

@end

detailviewcontroller.h

Code:


#import <UIKit/UIKit.h>


@interface DetailViewController : UIViewController {
       
        IBOutlet UIScrollView *scrollView;
       
        IBOutlet UIImageView *cropImageView;
    IBOutlet UILabel *nameLabel;
    IBOutlet UILabel *levelLabel;
        IBOutlet UITextView *commentsTextView;
        IBOutlet UILabel *costLabel;
        IBOutlet UILabel *returnsLabel;
        IBOutlet UILabel *xpReturnsLabel;
        IBOutlet UILabel *revenueLabel;
    IBOutlet UILabel *timeLabel;
        IBOutlet UILabel *boostingLabel;
        IBOutlet UILabel *spoilageLabel;
        IBOutlet UILabel *coinsLabel;
        IBOutlet UILabel *xpLabel;
 
       
    NSDictionary *cropData;
}


@property (nonatomic, retain) UIImageView *cropImageView;
@property (nonatomic, retain) UILabel *nameLabel;
@property (nonatomic, retain) UILabel *levelLabel;
@property (nonatomic, retain) UITextView *commentsTextView;
@property (nonatomic, retain) UILabel *costLabel;
@property (nonatomic, retain) UILabel *returnsLabel;
@property (nonatomic, retain) UILabel *xpReturnsLabel;
@property (nonatomic, retain) UILabel *revenueLabel;
@property (nonatomic, retain) UILabel *timeLabel;
@property (nonatomic, retain) UILabel *boostingLabel;
@property (nonatomic, retain) UILabel *spoilageLabel;
@property (nonatomic, retain) UILabel *coinsLabel;
@property (nonatomic, retain) UILabel *xpLabel;



- (id)initWithcropData:(NSDictionary *)data nibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil;


@end

detailviewcontroller.m
Code:

#import "DetailViewController.h"


@implementation DetailViewController

@synthesize cropImageView, nameLabel, levelLabel, commentsTextView, costLabel, returnsLabel, xpReturnsLabel, revenueLabel, timeLabel, boostingLabel, spoilageLabel, coinsLabel, xpLabel;


       

- (id)initWithcropData:(NSDictionary *)data nibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
    if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) {
        cropData = data;
    }
    return self;
}


/*
 // The designated initializer.  Override if you create the controller programmatically and want to perform customization that is not appropriate for viewDidLoad.
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
    if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) {
        // Custom initialization
    }
    return self;
}
*/

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

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


// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
    cropImageView.image = [UIImage imageNamed:[cropData valueForKey:@"cropImage"]];
    nameLabel.text = [cropData valueForKey:@"name"];
    levelLabel.text = [NSString stringWithFormat:@"Level %@ ", [cropData valueForKey:@"level"]];
        commentsTextView.text = [cropData valueForKey:@"comments"];
        costLabel.text = [NSString stringWithFormat:@"Cost %@ coins", [cropData valueForKey:@"cost"]];
        returnsLabel.text = [NSString stringWithFormat:@"Returns %@ coins", [cropData valueForKey:@"returns"]];
    xpReturnsLabel.text = [NSString stringWithFormat:@"XP Returns %@ ", [cropData valueForKey:@"xpReturns"]];
    revenueLabel.text = [NSString stringWithFormat:@"Profits %@ coins", [cropData valueForKey:@"revenue"]];
        timeLabel.text = [NSString stringWithFormat:@"Harvest in %@ hour(s)", [cropData valueForKey:@"time"]];
        boostingLabel.text = [NSString stringWithFormat:@"To Boost %@ Mojo", [cropData valueForKey:@"boosting"]];
    spoilageLabel.text = [NSString stringWithFormat:@"Spoils in %@ hour(s)", [cropData valueForKey:@"spoilage"]];
    coinsLabel.text = [NSString stringWithFormat:@"Earn %@ coins per hour", [cropData valueForKey:@"coins"]];
        xpLabel.text = [NSString stringWithFormat:@"Earn %@ XP per hour", [cropData valueForKey:@"xp"]];

        [super viewDidLoad];
   
    scrollView.frame = CGRectMake(0, 0, 320, 460);
        [scrollView setContentSize:CGSizeMake(320, 678)];
   
}


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



// Override to allow orientations other than the default portrait orientation.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
        // Return YES for supported orientations.
        return YES; //(interfaceOrientation == UIInterfaceOrientationPortrait);
}



@end


thanks for any help and suggestions. If I have to I will start again using the example in chapter 10.

thepianoguy March 15th, 2012 09:34 AM

Do you have the code that you attempted to use to implement the search? Basically you need to add a UISearchBar and UISearchDisplayController and a separate array for handling the filtered elements of your table.
You display the SearchDisplay tableView when searching and the main tableView when not searching.

The book does not implement UISearchDisplayController since I don't believe it was available yet, but that is a better approach.

If you check the documentation for the UISearchDisplayController there is an example that should point you in the right direction.

Bob

Jule March 15th, 2012 09:09 PM

thanks
 
I thought it would be easy like the tutorial in chapter 10 but I was wrong.

I have coded wrong, or not used the right coding for this.

tried other examples, including Apples Tutorial but got into a big mess.

this code has 3 errors and 1 warning.


any help would be appreciated. hate to abandon this after all the work put into it. It works without the search perfectly but I would like a search function as there are a lot of items in table.


Code:

//  RootViewController.h
//  TableViewApp
//
//  Created by OZTech 2012.
//  Copyright OZTech 2012. All rights reserved.
//

#import "cropLibraryDao.h"
#import "cropListingViewCell.h"

@interface RootViewController : UITableViewController
<UISearchBarDelegate> {
   
        cropLibraryDao *dao;
       
    NSDictionary *cropTitles;
        NSArray *crops;
       
        IBOutlet cropListingViewCell *_cell;
       
        //---search---
    IBOutlet UISearchBar *searchBar;
    BOOL isSearchOn;
        BOOL canSelectRow;       
        NSMutableArray *listOfCrops;
        NSMutableArray *searchResult;
       
       
}

@property (nonatomic, retain) NSDictionary *cropTitles;
@property (nonatomic, retain) NSArray *crops;



//---search---
@property (nonatomic, retain) UISearchBar *searchBar;
- (void) doneSearching: (id)sender;
- (void) searchCropTableView;




@end



Code:

//  RootViewController.m
//  TableViewApp
//
//  Created by OZTech 2012.
//  Copyright OZTech 2012. All rights reserved.
//

#import "RootViewController.h"
#import "DetailViewController.h"

@implementation RootViewController

@synthesize cropTitles, crops;
@synthesize searchBar;


#define CELL_HEIGHT 80.0

- (void)viewDidLoad {
       
        // path to the propery list file
       
        NSString *path = [[NSBundle mainBundle] pathForResource:@"TestData" ofType:@"plist"];
       
        // load the list into the dictionary
        NSDictionary *dic = [[NSDictionary alloc] initWithContentsOfFile:path];
       
        // save the dictionary object to the property
        self.cropTitles = dic;
       
        NSArray *array = [[cropTitles allKeys] sortedArrayUsingSelector:@selector(compare:)];
        self.crops = array;
       
       
       
        [dic release];
       
        //---search---
       
        //---display the searchbar---
        self.tableView.tableHeaderView = searchBar;
        searchBar.autocorrectionType = UITextAutocorrectionTypeYes;
       
        //---copy all the crop names in the dictionary into the listOfCrops array---
        listOfCrops = [[NSMutableArray alloc] init];
        for (NSString *crop in array)
        {
              NSArray *crops = [cropTitles objectForKey:crop];
                for (NSString *title in crops)
                {
                        [listOfCrops addObject:title];
                }
        }
       
        //---used for storing the search result---
        searchResult = [[NSMutableArray alloc] init];
       
        isSearchOn = NO;
        canSelectRow = YES;
       
       
        [super viewDidLoad];
}       
        //---fired when the user taps on the searchbar---
        - (void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar {
                isSearchOn = YES;
                canSelectRow = NO;
                self.tableView.scrollEnabled = NO;
                //---add the Done button at the top---
                self.navigationItem.rightBarButtonItem = [[[UIBarButtonItem alloc]
                                                                                                  initWithBarButtonSystemItem:UIBarButtonSystemItemDone
                                                                                                  target:self action:@selector(doneSearching:)] autorelease];
        }
       
        //---done with the searching---
        - (void) doneSearching:(id)sender {
                isSearchOn = NO;
                canSelectRow = YES;
                self.tableView.scrollEnabled = YES;
                self.navigationItem.rightBarButtonItem = nil;
               
                //---hides the keyboard---
                [searchBar resignFirstResponder];
                //---refresh the TableView---
                [self.tableView reloadData];
        }
       
        //---fired when the user types something into the searchbar---
        - (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText {
                //[searchResult removeAllObjects]
                //---if there is something to search for---
                if ([searchText length] > 0) {
                        isSearchOn = YES;
                        canSelectRow = YES;
                        self.tableView.scrollEnabled = YES;
                        [self searchCropTableView];
                }
                else {               
                        //---nothing to search---
                        isSearchOn = NO;
                        canSelectRow = NO;
                        self.tableView.scrollEnabled = NO;
                }       
                [self.tableView reloadData];
        }
       
        //---performs the searching using the array of crops---
        - (void) searchCropTableView {
                //---clears the search result---
                [searchResult removeAllObjects];
               
                for (NSString *str in listOfCrops)
                {
                        NSRange titleResultsRange = [str rangeOfString:searchBar.text options:NSCaseInsensitiveSearch];
                        if (titleResultsRange.length > 0)
                                [searchResult addObject:str];
                }
        }
       
        //---fired when the user taps the Search button on the keyboard---
        - (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar {
                [self searchCropTableView];
        }
       
//-------
- (void)viewWillAppear:(BOOL)animated {
    dao = [[cropLibraryDao alloc] initWithLibraryName:@"TestData"];
    self.title = @"Crop List";
    [self.tableView deselectRowAtIndexPath:[self.tableView indexPathForSelectedRow] animated:YES];
}

/*
- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];
}
*/
/*
- (void)viewWillDisappear:(BOOL)animated {
        [super viewWillDisappear:animated];
}
*/
/*
- (void)viewDidDisappear:(BOOL)animated {
        [super viewDidDisappear:animated];
}
*/


 // Override to allow orientations other than the default portrait orientation.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
        // Return YES for supported orientations.
        return YES; //(interfaceOrientation == UIInterfaceOrientationPortrait);
}


- (void)didReceiveMemoryWarning {
        // Releases the view if it doesn't have a superview.
    [super didReceiveMemoryWarning];
       
        // Release any cached data, images, etc that aren't in use.
}

- (void)viewDidUnload {
        // Release anything that can be recreated in viewDidLoad or on demand.
        // e.g. self.myOutlet = nil;
}


#pragma mark Table view methods

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    if (isSearchOn)
                return 1;
        else
                return [crops count];
       
       
}


// Customize the number of rows in the table view.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    if (isSearchOn) {
                return [searchResult count];
        } else
        {
                return [dao libraryCount];
        }
}

// Customize the appearance of table view cells.

        /*
        - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
   
        static NSString *CellIdentifier = @"LibraryListingCell";
           
    cropListingViewCell *cell = (cropListingViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        [[NSBundle mainBundle] loadNibNamed:@"cropListingView" owner:self options:nil];
        cell = [_cell autorelease];
        _cell = nil;
    }
*/
- (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] autorelease];
                }
               
        if (isSearchOn) {               
                NSString *cellValue = [searchResult objectAtIndex:indexPath.row];
                cell.textLabel.text = cellValue;               
        } else
               
               
       
        cell.nameLabel.text = [[dao libraryItemAtIndex:indexPath.row] valueForKey:@"name"];   
    cell.levelLabel.text = [NSString stringWithFormat:@"Level %@ ",
                                    [[dao libraryItemAtIndex:indexPath.row] valueForKey:@"level"]];
    cell.cropImageView.image = [UIImage
                                imageNamed:[[dao libraryItemAtIndex:indexPath.row] valueForKey:@"cropImage"]];

       
       
    return cell;
}



// Override to support row selection in the table view.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    DetailViewController *controller = [[DetailViewController alloc]
                                        initWithcropData:[dao libraryItemAtIndex:indexPath.row]
                                        nibName:@"DetailViewController" bundle:[NSBundle mainBundle]];
    controller.title = [[dao libraryItemAtIndex:indexPath.row] valueForKey:@"name"];
    [self.navigationController pushViewController:controller animated:YES];
    [controller release];   
}

       
       
       

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
    return CELL_HEIGHT;
}

/*
// Override to support conditional editing of the table view.
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
    // Return NO if you do not want the specified item to be editable.
    return YES;
}
*/


/*
// Override to support editing the table view.
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
   
    if (editingStyle == UITableViewCellEditingStyleDelete) {
        // Delete the row from the data source.
        [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
    } 
    else if (editingStyle == UITableViewCellEditingStyleInsert) {
        // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view.
    } 
}
*/


/*
// Override to support rearranging the table view.
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath {
}
*/


/*
// Override to support conditional rearranging of the table view.
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath {
    // Return NO if you do not want the item to be re-orderable.
    return YES;
}
*/


- (void)dealloc {
        [crops release];
        [cropTitles release];
        [searchBar release];
    [super dealloc];
}


@end


thanks.

thepianoguy March 15th, 2012 11:38 PM

I will take a look at this tomorrow if I have the time. However, I don't recommend that you implement it the way it is done in this book. There are issues with the approach. A better way to implement the search is in "Professional iPhone and iPad Database Application Programming" Chapter 3. Download that code and see if that makes sense.

Bob

Jule March 16th, 2012 12:02 AM

thank you. I guessed that I was using the wrong code in this application, thanks for the reference will try that.

Jule March 16th, 2012 01:18 AM

thank you that chapter is exactly what I have been looking for. I had the right book but was looking at the wrong chapter. Will try it out and let you know how I get on.

Jule March 27th, 2012 01:15 AM

Database
 
the database program was want i was trying to use, but I couldn't find example. this is working out great from me. Thanks for the pointer.


All times are GMT -4. The time now is 04:09 AM.

Powered by vBulletin®
Copyright ©2000 - 2017, Jelsoft Enterprises Ltd.
2013 John Wiley & Sons, Inc.