I am getting the above warning message when trying to run my code.
NSDictionary *tempDictionary = nil;
if (self.tableView == self.searchDisplayController.searchResultsTableView) {
tempDictionary = [filteredCompanyArray objectAtIndex:indexPath.row];
}
else {
tempDictionary= [self.client_list objectAtIndex:indexPath.row];
}
It's been deprecated and did a google search but all I saw were tutorials in Swift.
I followed Ray Wenderlich tutorial here http://www.raywenderlich.com/16873/how-to-add-search-into-a-table-view but now i'm stuck.
#pragma mark Content Filtering
-(void)filterContentForSearchText:(NSString*)searchText scope:(NSString*)scope {
// Update the filtered array based on the search text and scope.
// Remove all objects from the filtered search array
[self.filteredCompanyArray removeAllObjects];
// Filter the array using NSPredicate
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"SELF.name contains[c] %#",searchText];
filteredCompanyArray = [NSMutableArray arrayWithArray:[self.client_list filteredArrayUsingPredicate:predicate]];
}
#pragma mark - UISearchDisplayController Delegate Methods
-(BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString {
// Tells the table data source to reload when text changes
[self filterContentForSearchText:searchString scope:
[[self.searchDisplayController.searchBar scopeButtonTitles] objectAtIndex:[self.searchDisplayController.searchBar selectedScopeButtonIndex]]];
// Return YES to cause the search result table view to be reloaded.
return YES;
}
-(BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchScope:(NSInteger)searchOption {
// Tells the table data source to reload when scope bar selection changes
[self filterContentForSearchText:self.searchDisplayController.searchBar.text scope:
[[self.searchDisplayController.searchBar scopeButtonTitles] objectAtIndex:searchOption]];
// Return YES to cause the search result table view to be reloaded.
return YES;
}
The recipe below worked for me. I just successfully updated multiple scenarios of former iOS 7 code.
Thanks also to the inspiration of Updating to the iOS 8 Search Controller and Apple's API Reference
Remove UISearchDisplayDelegate protocol, add UISearchResultsUpdating and maybe UISearchControllerDelegate instead
#interface YOURTableviewController : UIViewController <UITableViewDelegate, UITableViewDataSource, /*UISearchDisplayDelegate, <- Removed*/ UISearchResultsUpdating /* Added */, UISearchControllerDelegate /* Added */>
{
Add new UISearchController as property:
// New property
#property (nonatomic, strong) UISearchController *searchController;
// ...
#implementation YOURTableviewController
#synthesize searchController; // New property
and initialize the new property in the didLoad method
- (void)viewDidLoad
{
// New code start -
self.searchController = [[UISearchController alloc] initWithSearchResultsController:nil];
self.searchController.searchResultsUpdater = self;
self.searchController.delegate = self;
self.searchController.dimsBackgroundDuringPresentation = NO;
self.searchController.searchBar.delegate = self;
self.searchController.searchBar.barTintColor = [UIColor orangeColor];
[self.tableview setTableHeaderView:self.searchController.searchBar];
self.definesPresentationContext = YES;
// - New code end
// Previous code
//self.searchDisplayController.searchBar.barTintColor = [UIColor orange];
[super viewDidLoad];
}
Add new UISearchResultsUpdating methods, update UISearchBarDelegate methods, and maybe add helping extra method like below, and maybe also UISearchControllerDelegate methods
#pragma mark -
#pragma mark UISearchResultsUpdating
- (void)updateSearchResultsForSearchController:(UISearchController *)_searchController
{
NSString *searchString = _searchController.searchBar.text;
[self searchForText:searchString];
[self.tableview reloadData];
}
#pragma mark -
#pragma mark UISearchBarDelegate
- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText
{
[self updateSearchResultsForSearchController:self.searchController];
}
- (void)searchBar:(UISearchBar *)searchBar selectedScopeButtonIndexDidChange:(NSInteger)selectedScope
{
[self updateSearchResultsForSearchController:self.searchController];
}
// Extra method
- (void)searchForText:(NSString *)searchString
{
/* Put here everything that is in the method:
- (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString
...BUT WITH NO RETURN VALUE */
}
#pragma mark -
#pragma mark UISearchControllerDelegate
- (void)willPresentSearchController:(UISearchController *)searchController
{
//..
}
- (void)didPresentSearchController:(UISearchController *)searchController
{
//..
}
- (void)willDismissSearchController:(UISearchController *)searchController
{
//..
}
- (void)didDismissSearchController:(UISearchController *)searchController
{
//..
}
Replace and remove obsolete UISearchDisplayDelegate method(s)
#pragma mark -
#pragma mark UISearchDisplayDelegate
- (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString
{ ... }
Replace 'searchDisplayController' everywhere with 'searchController'
Make replacements
Code like:
if (tableView == self.searchDisplayController.searchResultsTableView)
can be replaced with
if (self.searchController.isActive)
Code like:
[self.searchDisplayController setActive:YES];
can be replaced with
[self.searchController setActive:YES];
Yes UISearchDisplay Controller is deprecated, you should use UISearchController instead
Create Search Controller First
#property (strong, nonatomic) UISearchController *searchController;
Initialise Search controller properties
self.searchController = [[UISearchController alloc] initWithSearchResultsController:nil];
self.searchController.searchResultsUpdater = self;
self.searchController.dimsBackgroundDuringPresentation = NO;
Bind Search controller with your table view
self.tableView.tableHeaderView = self.searchController.searchBar;
Implement UISearchResultUpdating delegate
- (void)updateSearchResultsForSearchController:(UISearchController *)searchController
{
NSString *searchString = searchController.searchBar.text;
[self searchForText:searchString
scope:searchController.searchBar.selectedScopeButtonIndex];
[self.tableView reloadData];
}
You Can also use your filter method to filter result
Your search logic will go here
-(void)filterContentForSearchText:(NSString*)searchText scope:(NSString*)scope
More detail you can find
http://useyourloaf.com/blog/updating-to-the-ios-8-search-controller/
As UISearchDisplayController is deprecated, you need to use UISearchController for your purpose. Follow this link Using UISearchController
Another link that might be useful for you UISearchController Vs UISearchDisplayController
Related
Not sure if the title makes to much sense so here is a description of what is going on:
I have a UITableViewController that is using a custom UITableViewCell for its data. I am then manually adding a searchBar to the header of the UITableView and setting it up based on this tutorial : http://useyourloaf.com
Now the searchBar is setup, it looks like it is working but the issue is that I am not actually getting any results and the table is not loading properly (the search results, it load the base data fine)
Here is my code for comparison. I know I must be missing something simple...
** I am hardcoding the data for my cells at the moment, this will change to a core data model once I can fix this issue... although this may be the base of my issue as I am hardcoding the cells at each IP **
#implementation CharitiesTableViewController{
NSArray *charities;
NSArray *searchResults;
}
- (void)viewDidLoad {
[super viewDidLoad];
[self setColors];
[_charityTable registerNib:[UINib nibWithNibName:#"CharityTableViewCell" bundle:[NSBundle mainBundle]] forCellReuseIdentifier:#"charityCell"];
self.tableView.rowHeight = UITableViewAutomaticDimension;
self.tableView.estimatedRowHeight = 350.0;
// self.tableView.contentInset = UIEdgeInsetsMake(-2.0f, 0.0f, 0.0f, 0.0);
self.searchController = [[UISearchController alloc] initWithSearchResultsController:nil];
self.searchController.searchResultsUpdater = self;
self.searchController.dimsBackgroundDuringPresentation = NO;
self.searchController.searchBar.delegate = self;
self.searchController.delegate = self;
self.tableView.tableHeaderView = self.searchController.searchBar;
self.definesPresentationContext = YES;
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
- (void) setColors {
}
#pragma mark - Search Controller
- (void)updateSearchResultsForSearchController:(UISearchController *)searchController {
NSString *searchString = searchController.searchBar.text;
[self searchForText:searchString];
[self.tableView reloadData];
}
- (void)searchForText:(NSString *)searchText {
NSPredicate *resultPredicate = [NSPredicate predicateWithFormat:#"name contains[c] %#", searchText];
searchResults = [charities filteredArrayUsingPredicate:resultPredicate];
}
- (void)willPresentSearchController:(UISearchController *)searchController {
self.navigationController.navigationBar.translucent = YES;
}
-(void)willDismissSearchController:(UISearchController *)searchController {
self.navigationController.navigationBar.translucent = NO;
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
if (tableView == _charityTable)
{
return 1;
}
return [searchResults count];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return 1;
}
- (CGFloat)tableView:(UITableView*)tableView heightForHeaderInSection:(NSInteger)section {
return SectionSpacer;
}
- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section {
return SectionSpacer;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
switch (indexPath.section) {
case 0:{
CharityTableViewCell *cell = (CharityTableViewCell *)[tableView dequeueReusableCellWithIdentifier:#"charityCell"];
cell.charityImage.image = [UIImage imageNamed:#"cleanup"];
cell.charityName.text = #"Garbage cleanup - Crowchild";
cell.charityTagLine.text = #"City of Calgary";
cell.charityDescriptionShort.text = #"We are rounding up anyone that wants to help clean up the grass and nearby areas close to crowchild.";
return cell;
}
default:{
UITableViewCell *cell;
return cell;
}
}
}
#end
Thanks for you help!
I am silly.... I was trying to do this without initializing the data like a com mentor said. The code is correct and if anyone has any similar issues make sure your array of data actually has data in it...
I am using UISearchbar in tableview controller in storyboard.
And searchbar returnKeyType is UIReturnKeySearch.
Its working fine with iOS7 but returnKeyType is not working with iOS8.
in iOS8, return key appears every time in keyboard.
I tried to set returnkeytype in viewDidLoad method of controller too.
What I need to do to set returnKeyType = UIReturnKeySearch in iOS8?
I think you can go with your hard codded logic for right now.
I will update if I will get better solution for your problem.
-(void)viewDidLoad {
[self setReturnKeyTypeSearchForView:searchBar];
}
-(void)setReturnKeyTypeSearchForView:(UIView *)view
{
for (id subView in view.subviews) {
if ([subView isKindOfClass:[UITextField class]]) {
[subView setReturnKeyType:UIReturnKeySearch];
}
else {
[self setReturnKeyTypeSearchForView:subView];
}
}
if ([view isKindOfClass:[UITextField class]]) {
[(UITextField *)view setReturnKeyType:UIReturnKeySearch];
}
}
Try making IBOutlet of your SearchBar
#property (weak, nonatomic) IBOutlet UISearchBar *searchBar;
and add the below line code to your viewDidLoad Method
// if u want Done return key and change accordingly.
_searchBar.returnKeyType = UIReturnKeyDone;
SearchViewController.h
//
#import <UIKit/UIKit.h>
#interface SearchViewController : UIViewController
<UISearchBarDelegate, UITableViewDataSource> {
NSMutableArray *tableData;
UIView *disableViewOverlay;
UITableView *theTableView;
UISearchBar *theSearchBar;
}
#property(retain) NSMutableArray *tableData;
#property(retain) UIView *disableViewOverlay;
#property (nonatomic, retain) IBOutlet UITableView *theTableView;
#property (nonatomic, retain) IBOutlet UISearchBar *theSearchBar;
- (void)searchBar:(UISearchBar *)searchBar activate:(BOOL) active;
#end
SearchViewController.m
//
#import "SearchViewController.h"
#implementation SearchViewController
#synthesize tableData;
#synthesize disableViewOverlay;
#synthesize theSearchBar;
#synthesize theTableView;
// Initialize tableData and disabledViewOverlay
- (void)viewDidLoad {
[super viewDidLoad];
self.tableData =[[NSMutableArray alloc]init];
self.disableViewOverlay = [[UIView alloc]
initWithFrame:CGRectMake(0.0f,44.0f,320.0f,416.0f)];
self.disableViewOverlay.backgroundColor=[UIColor blackColor];
self.disableViewOverlay.alpha = 0;
}
// Since this view is only for searching give the UISearchBar
// focus right away
- (void)viewDidAppear:(BOOL)animated {
[self.theSearchBar becomeFirstResponder];
[super viewDidAppear:animated];
}
#pragma mark -
#pragma mark UISearchBarDelegate Methods
- (void)searchBar:(UISearchBar *)searchBar
textDidChange:(NSString *)searchText {
// We don't want to do anything until the user clicks
// the 'Search' button.
// If you wanted to display results as the user types
// you would do that here.
}
- (void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar {
// searchBarTextDidBeginEditing is called whenever
// focus is given to the UISearchBar
// call our activate method so that we can do some
// additional things when the UISearchBar shows.
[self searchBar:searchBar activate:YES];
}
- (void)searchBarTextDidEndEditing:(UISearchBar *)searchBar {
// searchBarTextDidEndEditing is fired whenever the
// UISearchBar loses focus
// We don't need to do anything here.
}
- (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar {
// Clear the search text
// Deactivate the UISearchBar
searchBar.text=#"";
[self searchBar:searchBar activate:NO];
}
- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar {
// Do the search and show the results in tableview
// Deactivate the UISearchBar
// You'll probably want to do this on another thread
// SomeService is just a dummy class representing some
// api that you are using to do the search
NSArray *results = [SomeService doSearch:searchBar.text];
[self searchBar:searchBar activate:NO];
[self.tableData removeAllObjects];
[self.tableData addObjectsFromArray:results];
[self.theTableView reloadData];
}
// We call this when we want to activate/deactivate the UISearchBar
// Depending on active (YES/NO) we disable/enable selection and
// scrolling on the UITableView
// Show/Hide the UISearchBar Cancel button
// Fade the screen In/Out with the disableViewOverlay and
// simple Animations
- (void)searchBar:(UISearchBar *)searchBar activate:(BOOL) active{
self.theTableView.allowsSelection = !active;
self.theTableView.scrollEnabled = !active;
if (!active) {
[disableViewOverlay removeFromSuperview];
[searchBar resignFirstResponder];
} else {
self.disableViewOverlay.alpha = 0;
[self.view addSubview:self.disableViewOverlay];
[UIView beginAnimations:#"FadeIn" context:nil];
[UIView setAnimationDuration:0.5];
self.disableViewOverlay.alpha = 0.6;
[UIView commitAnimations];
// probably not needed if you have a details view since you
// will go there on selection
NSIndexPath *selected = [self.theTableView
indexPathForSelectedRow];
if (selected) {
[self.theTableView deselectRowAtIndexPath:selected
animated:NO];
}
}
[searchBar setShowsCancelButton:active animated:YES];
}
#pragma mark -
#pragma mark UITableViewDataSource Methods
- (NSInteger)tableView:(UITableView *)tableView
numberOfRowsInSection:(NSInteger)section {
return [tableData count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *MyIdentifier = #"SearchResult";
UITableViewCell *cell = [tableView
dequeueReusableCellWithIdentifier:MyIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc]
initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:MyIdentifier] autorelease];
}
id *data = [self.tableData objectAtIndex:indexPath.row];
cell.textLabel.text = data.name;
return cell;
}
#pragma mark -
#pragma mark Memory Management Methods
- (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 any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (void)dealloc {
[theTableView release], theTableView = nil;
[theSearchBar release], theSearchBar = nil;
[tableData dealloc];
[disableViewOverlay dealloc];
[super dealloc];
}
#end
Building a SearchView with UISearchBar and UITableView
this might helps you :)
I'm not sure if I understood your question correctly. You want to have "search" button instead of "return" button, right? There is a new SearchController in ios 8, give it a try:
YourTableViewController.h
#interface YourTableViewController : UITableViewController<UISearchResultsUpdating>
#end
And now the implementation:
YourTableViewController.m
- (void)viewDidLoad {
// initializing with the same controller as presenting
UISearchController *searchController = [[UISearchController alloc] initWithSearchResultsController:nil];
searchController.searchResultsUpdater = self;
searchController.searchBar.frame = CGRectMake(searchController.searchBar.frame.origin.x, searchController.searchBar.frame.origin.y, searchController.searchBar.frame.size.width, 44.0f);
searchController.dimsBackgroundDuringPresentation = NO;
searchController.searchBar.delegate = self;
searchController.searchBar.returnKeyType = UIReturnKeySearch; //should be search by default.. you can change to whatever you want.
// adding searchBar into HeaderView
self.tableView.tableHeaderView = searchController.searchBar;
// just to be able to present results on the same controller
self.definesPresentationContext = YES;
}
You also have to implement method from UISearchResultsUpdating protocol:
- (void)updateSearchResultsForSearchController:(UISearchController *)searchController {
// you can leave it blank
}
EDIT: If it is not what you were looking for please comment, so I can update my answer accordingly
try this in viewDidLoad:
UITextField *txfSearchField = [yourSearchbar valueForKey:#"_searchField"];
if([txfSearchField conformsToProtocol:#protocol(UITextInputTraits)]) {
[txfSearchField setReturnKeyType:UIReturnKeyDefault];
}
I've implemented UISearchControl (iOS8 version which is slightly different then previous ones). It seems to be firing correctly when I type stuff in according to the NSLog statement seen below, only issue is it the UITableView actually never gets updated, and I added a NSLog to the } else { part of the numberOfRowsInSection to confirm that it's not called like so:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if (tableView == self.tableView) {
return self.objects.count;
} else {
// NOT BEING FIRED WHEN STUFF IS TYPED IN SEARCH BAR?
NSLog(#"Search Results Returned in TableView");
return self.searchResults.count;
}
}
Although these methods are firing fine...and updating the searchResults array correctly according to the NSLog added in the updateFilter method:
#pragma mark - UISearchResultsUpdating
-(void)updateSearchResultsForSearchController:(UISearchController *)searchController {
NSString *searchString = [self.searchController.searchBar text];
[self updateFilteredContentForSaleName:searchString];
// ASSUMING THIS IS WHAT CAUSES TABLEVIEW TO REFRESH, BUT ISNT REFRESHING IT WITH NEW ARRAY?
[((UITableViewController *)self.searchController.searchResultsController).tableView reloadData];
}
#pragma mark - Content Filtering
- (void)updateFilteredContentForSaleName:(NSString *)saleName {
[self.searchResults removeAllObjects];
for (PFObject *sale in self.objects)
{
NSString *saleTitle = [sale objectForKey:#"name"];
if ([[saleTitle lowercaseString] hasPrefix:[saleName lowercaseString]])
{
[self.searchResults addObject:sale];
}
}
// THIS LOG SHOWS SEARCH RESULTS CORRECTLY HOW THEY SHOULD BE, JUST NO UPDATE TO UITABLEVIEW
NSLog(#"%#", self.searchResults);
}
But simply no update to the tableview...
Any idea why this is? Am I calling the refresh wrong here?:
[((UITableViewController *)self.searchController.searchResultsController).tableView reloadData];
I've tried PFQueryTableViewController * too since that's essentially what I'm using for actual view controller, but no luck.
EDIT
Here is the code used to create the UISearchControl
#interface LocalSalesViewController () <UISearchResultsUpdating>
#property (nonatomic, strong) UISearchController *searchController;
#property (nonatomic, strong) NSMutableArray *searchResults; // Filtered search results
#end
#implementation LocalSalesViewController
- (id)initWithCoder:(NSCoder *)aCoder {
self = [super initWithCoder:aCoder];
if (self) {
self.parseClassName = #"Sales";
self.pullToRefreshEnabled = YES;
self.paginationEnabled = YES;
self.objectsPerPage = 25;
}
return self;
}
- (void)viewDidLoad {
[super viewDidLoad];
self.searchResults = [NSMutableArray array];
self.searchController = [[UISearchController alloc] initWithSearchResultsController:nil];
self.searchController.searchResultsUpdater = self;
self.searchController.searchBar.frame = CGRectMake(self.searchController.searchBar.frame.origin.x, self.searchController.searchBar.frame.origin.y, self.searchController.searchBar.frame.size.width, 44.0);
self.tableView.tableHeaderView = self.searchController.searchBar;
self.definesPresentationContext = YES;
}
I've created a UISearchBar in one of my ViewControllers that contain different containers that link to other ViewControllers. This UISearchBar is in the parent ViewController. I am trying to grab the text that was entered in the search bar to be used to send to another ViewController The UISearchBar was created in StoryBoard. I am using the following methods to try and receive information from the Search Bar:
- (void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar {
NSLog(#"searching");
}
- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText {
NSLog(#"Text change");
}
- (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar {
NSLog(#"Cancel clicked");
}
- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar {
NSLog(#"Search Clicked");
}
Non of these functions above seem to run, I am not sure why. Suggestions or thoughts?
UPDATE:
Here is what I am using to initiate the Search Bar now:
_aSearchBar = [[UISearchBar alloc] initWithFrame:CGRectZero];
[_aSearchBar sizeToFit];
_aSearchBar.delegate = self;
_aSearchBar.placeholder = #"Search YouTube...";
_searchDC = [[UISearchDisplayController alloc] initWithSearchBar:_aSearchBar contentsController:self];
[self performSelector:#selector(setSearchDisplayController:) withObject:_searchDC];
_searchDC.delegate = self;
_searchDC.searchResultsDataSource = self;
_searchDC.searchResultsDelegate = self;
[_aSearchBar release];
NSLog(#"%#",[_searchDC.delegate class]); <------ this prints home which is the correct class
Now the only issue is, I can't see the search bar anymore?
If the delegate methods are not being called it means that the UISearchBar doesn't know where to delegate the optional methods in UISearchBarDelegate protocol.
So the ViewController that implements these methods
- (void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar {
NSLog(#"searching");
}
- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText {
NSLog(#"Text change");
}
- (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar {
NSLog(#"Cancel clicked");
}
- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar {
NSLog(#"Search Clicked");
}
must be set as the delegate of the UISearchBar. To make sure that the correct ViewController is set as the delegate of the UISearchBar I would print the
[searchBar.delegate class]
If this returns nil or some other class name then the one you expect, you will know where the problems comes from.
Hope this helps.
UPDATE
Ok, I just created a Single View Application and dragged a UISearchBar on the storyboard. Then I added an outlet for the UISearchBar called searchBar. Then I made the ViewController implement the UISearchBarDelegate protocol. Then in ViewDidLoad I set the searchBar.delegate = self. After I added all the delegate methods listed above everything worked... So the only thing that I can think of now is that the ViewController is not implementing the protocol
#interface ViewController () <UISearchBarDelegate>
Here's the ViewController source code:
#import "ViewController.h"
#interface ViewController () <UISearchBarDelegate>
#property (weak, nonatomic) IBOutlet UISearchBar *searchBar;
#end
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.searchBar.delegate = self;
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - UISearchBarDelegate
- (void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar {
NSLog(#"searching");
}
- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText {
NSLog(#"Text change");
}
- (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar {
NSLog(#"Cancel clicked");
}
- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar {
NSLog(#"Search Clicked");
}
I am not sure how I could approach this, I am just learning about tables. I have the code below that filters an array as you type. The search bar moves up and the controller goes dark below the search, however when I type the first letter, the results don't generate underneath.
This is a modification of the sample project from Apple. Tablesearch
What am I missing?
Also the keyboard seems to drag behind when the new VC loads
Thank you in advance
// itemsSearchViewController.m
#import "itemsSearchViewController.h"
#import "SearchRecipeViewController.h"
#import "firstAppDelegate.h"
#interface itemsSearchViewController ()
#end
#implementation itemsSearchViewController
#synthesize listContent, filteredListContent, savedSearchTerm, savedScopeButtonIndex, searchWasActive;
#synthesize delegate;
#synthesize itemsToPass;
/*
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
// Custom initialization
}
return self;
}
#pragma mark -
#pragma mark Lifecycle methods
*/
- (void)viewDidLoad
{
//[super viewDidLoad];
self.title = #"items Search";
//write names of itemss to array
NSString *path =[[NSBundle mainBundle] pathForResource:#"possibleitemss" ofType:#"plist"];
NSArray *content = [NSArray arrayWithContentsOfFile:path];
self.listContent =[NSArray arrayWithArray:content];
if([content count] == 0)
{
NSLog(#"nsma is empty");
}
NSLog(#"list contents%#", listContent);
// NSLog(#"list content = %#", listContent);
// create a filtered list that will contain products for the search results table.
self.filteredListContent = [NSMutableArray arrayWithCapacity:[self.listContent count]];
// restore search settings if they were saved in didReceiveMemoryWarning.
if (self.savedSearchTerm)
{
[self.searchDisplayController setActive:self.searchWasActive];
[self.searchDisplayController.searchBar setSelectedScopeButtonIndex:self.savedScopeButtonIndex];
[self.searchDisplayController.searchBar setText:savedSearchTerm];
self.savedSearchTerm = nil;
}
[self.tableView reloadData];
self.tableView.scrollEnabled = YES;
}
- (void)viewDidUnload
{
//self.filteredListContent = nil;
}
- (void)viewDidDisappear:(BOOL)animated
{
// save the state of the search UI so that it can be restored if the view is re-created
self.searchWasActive = [self.searchDisplayController isActive];
self.savedSearchTerm = [self.searchDisplayController.searchBar text];
self.savedScopeButtonIndex = [self.searchDisplayController.searchBar selectedScopeButtonIndex];
}
- (void)dealloc
{
[listContent release];
[filteredListContent release];
[super dealloc];
}
#pragma mark -
#pragma mark UITableView data source and delegate methods
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
/*
If the requesting table view is the search display controller's table view, return the count of
the filtered list, otherwise return the count of the main list.
*/
if (tableView == self.searchDisplayController.searchResultsTableView)
{
return [self.filteredListContent count];
}
else
{
return [self.listContent count];
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *kCellID = #"cellID";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellID];
if (cell == nil)
{
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:kCellID] autorelease];
}
/*
If the requesting table view is the search display controller's table view, configure the cell using the filtered content, otherwise use the main list.
*/
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
/*
If the requesting table view is the search display controller's table view, configure the next view controller using the filtered content, otherwise use the main list.
*/
}
#pragma mark -
#pragma mark Content Filtering
//as user types this is happening
-(void) filterResults:(NSString *)searchText{
NSMutableArray *test = [NSMutableArray arrayWithArray:self.listContent];
[self.filteredListContent removeAllObjects]; // First clear the filtered array.
for (int i=0; i<[test count]; i++) {
NSString *stringResult = [test objectAtIndex:i];
NSComparisonResult result = [stringResult compare:searchText options:(NSCaseInsensitiveSearch|NSDiacriticInsensitiveSearch) range:NSMakeRange(0, [searchText length])];
if (result == NSOrderedSame){
[self.filteredListContent addObject:stringResult];
}
}
[self.filteredListContent sortUsingSelector:#selector(localizedCaseInsensitiveCompare:)];//sort alphabetically
NSLog(#"filtered results = %#",self.filteredListContent);
}
#pragma mark -
#pragma mark UISearchDisplayController Delegate Methods
- (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString
{items
[self filterResults:searchString];
//[self filterContentForSearchText:searchString scope:
// [[self.searchDisplayController.searchBar scopeButtonTitles] objectAtIndex:[self.searchDisplayController.searchBar selectedScopeButtonIndex]]];
// Return YES to cause the search result table view to be reloaded.
return YES;
}
- (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchScope:(NSInteger)searchOption
{
[self filterContentForSearchText:[self.searchDisplayController.searchBar text] scope:
[[self.searchDisplayController.searchBar scopeButtonTitles] objectAtIndex:searchOption]];
// Return YES to cause the search result table view to be reloaded.
return YES;
}
- (IBAction)itemsSelected: (id)sender{
if ( self.delegate != nil && [self.delegate respondsToSelector:#selector(showSearchRecipeView)] ) {
[self.delegate showSearchRecipeView];
}
}
#end
My guess is that one the below is out:
The resource path is possibleitemss -- is that a typo?
Have you verified that the arrays have been populated?
Is your searchDisplayController:shouldReloadTableForSearchScope: actually returning yes?
In other words, I'd step into each of these functions and watch the that the flow is behaving how you expected, and that your arrays are in fact populated.
Let me know if that helps.