I need help setting up a PFQTVC search function. I have most of it complete but am stuck on how to switch the local data (self.tabledata) for the remote data (self.objects). Here is my code. Im stuck on the filterContentForSearchText method.
#import "ViewController.h"
#interface ViewController () <UISearchDisplayDelegate>
#property (nonatomic, strong) NSArray *tableData;
#property (nonatomic, strong) NSMutableArray *searchResult;
#end
#implementation ViewController
- (id)initWithCoder:(NSCoder *)aCoder
{
self = [super initWithCoder:aCoder];
if (self) {
// Custom the table
// The className to query on
self.parseClassName = #"profs";
// The key of the PFObject to display in the label of the default cell style
self.textKey = #"name";
// Whether the built-in pull-to-refresh is enabled
self.pullToRefreshEnabled = YES;
// Whether the built-in pagination is enabled
self.paginationEnabled = YES;
// The number of objects to show per page
self.objectsPerPage = 500;
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// self.tableData = #[#"One",#"Two",#"Three",#"Twenty-one"];
self.searchResult = [NSMutableArray arrayWithCapacity:[self.objects count]];
}
- (PFQuery *)queryForTable
{
PFQuery *query;
query = [PFQuery queryWithClassName:self.parseClassName];
// If no objects are loaded in memory, we look to the cache first to fill the table
// and then subsequently do a query against the network.
/* if ([self.objects count] == 0) {
query.cachePolicy = kPFCachePolicyCacheThenNetwork;
}*/
return query;
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if (tableView == self.searchDisplayController.searchResultsTableView)
{
return [self.searchResult count];
}
else
{
return [self.objects count];
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath object:(PFObject *)object
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
if (tableView == self.searchDisplayController.searchResultsTableView)
{
cell.textLabel.text = [self.searchResult objectAtIndex:indexPath.row];
}
else
{
cell.textLabel.text = [object objectForKey:#"name"];
}
return cell;
}
- (void)filterContentForSearchText:(NSString*)searchText scope:(NSString*)scope
{
[self.searchResult removeAllObjects];
NSPredicate *resultPredicate = [NSPredicate predicateWithFormat:#"SELF contains[c] %#", searchText];
self.searchResult = [NSMutableArray arrayWithArray: [self.tableData filteredArrayUsingPredicate:resultPredicate]];
}
-(BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString
{
[self filterContentForSearchText:searchString scope:[[self.searchDisplayController.searchBar scopeButtonTitles] objectAtIndex:[self.searchDisplayController.searchBar selectedScopeButtonIndex]]];
return YES;
}
#end
Try this:
- (void)filterContentForSearchText:(NSString*)searchText scope:(NSString*)scope
{
[self.searchResult removeAllObjects];
NSPredicate *resultPredicate = [NSPredicate predicateWithFormat:#"%K CONTAINS[c] %#", YOUR_FIELD_TO_COMPARE, searchText];
self.searchResult = [NSMutableArray arrayWithArray: [self.tableData filteredArrayUsingPredicate:resultPredicate]];
}
YOUR_FIELD_TO_COMPARE is the field name for the value you are comparing in the search, e.g. "name"
Related
Here I have a Search Bar on the top of the UIViewController, and also a UITableView below the Search Bar.
When I don't Search things, the tableView could display things well, but when I search, the searchResultTableView can only show some white cell, not the correct result.
Here is the .h file:
#import <UIKit/UIKit.h>
#interface MySearchViewController : UIViewController <UITableViewDelegate, UITableViewDataSource>
#property (weak, nonatomic) IBOutlet UITableView *myTableView;
- (void)reloadView;
#end
And here is the .m file:
#import "MySearchViewController.h"
#import "MyEventInfo.h"
#import "MyEventTableViewCell.h"
#import "MyEventDetailViewController.h"
#interface MySearchViewController ()
#property NSUserDefaults *usrDefault;
#end
#implementation MySearchViewController {
NSMutableArray *events;
NSArray *searchResults;
}
- (void)viewDidLoad {
[super viewDidLoad];
self.usrDefault = [NSUserDefaults standardUserDefaults];
events = [[NSMutableArray alloc] init];
[self extractEventArrayData];
}
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:YES];
[self reloadView];
}
- (void)reloadView {
NSLog(#"reloadView");
events = [[NSMutableArray alloc] init];
[self extractEventArrayData];
[self.myTableView reloadData];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void)extractEventArrayData {
NSArray *dataArray = [[NSArray alloc] initWithArray:[self.usrDefault objectForKey:#"eventDataArray"]];
for (NSData *dataObject in dataArray) {
MyEventInfo *eventDecodedObject = [NSKeyedUnarchiver unarchiveObjectWithData:dataObject];
[events addObject:eventDecodedObject];
}
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if (tableView == self.myTableView) {
return [events count];
} else {
NSLog(#"searchResults count:%lu",(unsigned long)[searchResults count]);
return [searchResults count];
}
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 360;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"CustomTableCell";
MyEventTableViewCell *cell = (MyEventTableViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
// Configure the cell...
if (cell == nil) {
cell = [[MyEventTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
// Display MyEventTableViewCell in the table cell
MyEventInfo *event = nil;
if (tableView == self.myTableView) {
event = [events objectAtIndex:indexPath.row];
} else {
event = [searchResults objectAtIndex:indexPath.row];
NSLog(#"name of event:%#", event.nameOfEvent);
}
cell.nameOfEvent.text = event.nameOfEvent;
cell.imageOfEvent.image = [UIImage imageNamed:event.imageOfEvent];
cell.timeOfEvent.text = event.timeOfEvent;
cell.locationOfEvent.text = event.locationOfEvent;
cell.dateOfEvent.text = event.dateOfEvent;
return cell;
}
- (void)filterContentForSearchText:(NSString*)searchText
{
NSPredicate *resultPredicate = [NSPredicate predicateWithFormat:#"nameOfEvent contains[c] %#", searchText];
searchResults = [events filteredArrayUsingPredicate:resultPredicate];
}
-(BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString
{
[self filterContentForSearchText:searchString];
return YES;
}
#end
And on the storyboard I've already set the tableView's delegate and datasource to self. This drives me crazy, I cannot figure out what's wrong. Could someone help me out? Thanks.
when searching, cell's objects were all null, and had nothing in itself
when not searching, the cell is well with objects that had content the same as event
I am trying to display data in different sections using PFQueryTableViewController. The code suggested in https://parse.com/questions/using-pfquerytableviewcontroller-for-uitableview-sections seemed to work, but I couldn't get the data to load on self.objects. Here is my code:
#import "AKAdminViewStudentsViewController.h"
#interface AKAdminViewStudentsViewController ()
#property (strong, nonatomic) NSMutableDictionary *sections;
#property (strong, nonatomic) NSMutableDictionary *sectionToClassMap;
#end
#implementation AKAdminViewStudentsViewController
#synthesize sections = _sections;
#synthesize sectionToClassMap = _sectionToClassMap;
- (id)initWithCoder:(NSCoder *)aDecoder
{
self = [super initWithCoder:aDecoder];
if (self) {
self.parseClassName = #"Students";
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
[self.tableView reloadData];
NSLog(#"sections found: %#", self.sections); // returns null
NSLog(#"sectionToClassMap: %#", self.sectionToClassMap); // returns null
NSLog(#"objects in table: %#", self.objects); // this found to be empty
}
...
#pragma mark - Tableview methods
- (PFQuery *)queryForTable
{
PFQuery *queryStudents = [PFQuery queryWithClassName:#"Students"];
[queryStudents whereKey:#"student_admin" equalTo:[PFUser currentUser]];
if ([self.objects count]==0) {
queryStudents.cachePolicy = kPFCachePolicyCacheThenNetwork;
}
[queryStudents orderByAscending:#"class_name"];
return queryStudents;
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return self.sections.allKeys.count;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
NSString *className = [self classForSection:section];
NSArray *rowIndicesInSection = [self.sections objectForKey:className];
return rowIndicesInSection.count;
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
NSString *className = [self classForSection:section];
return className;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath object:(PFObject *)object
{
static NSString *CellIdentifier = #"Students";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
if (cell==nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
}
// Configure cell
cell.textLabel.text = [NSString stringWithFormat:#"%#", object[#"full_name"]];
NSDateFormatter *formatDate = [[NSDateFormatter alloc] init];
[formatDate setDateStyle:NSDateFormatterShortStyle];
cell.detailTextLabel.text = [NSString stringWithFormat:#"%#", [formatDate stringFromDate:object[#"createdAt"]]];
return cell;
}
#pragma mark - Helper methods
- (void)objectsDidLoad:(NSError *)error
{
[super objectsDidLoad:error];
// Clear data before loading
[self.sections removeAllObjects];
[self.sectionToClassMap removeAllObjects];
NSInteger section = 0;
NSInteger rowIndex = 0;
for (PFObject *object in self.objects) {
NSString *className = [object objectForKey:#"class_name"];
NSMutableArray *objectsInSection = [self.sections objectForKey:className];
if (!objectsInSection) {
objectsInSection = [NSMutableArray array];
// Create new section for new class found
[self.sectionToClassMap setObject:className forKey:[NSNumber numberWithInt:section++]];
}
[objectsInSection addObject:[NSNumber numberWithInt:rowIndex++]];
[self.sections setObject:objectsInSection forKey:className];
}
}
- (PFObject *)objectAtIndexPath:(NSIndexPath *)indexPath
{
NSString *className = [self classForSection:indexPath.section];
NSArray *rowIndicesInSection = [self.sections objectForKey:className];
NSNumber *rowIndex = [rowIndicesInSection objectAtIndex:indexPath.row];
return [self.objects objectAtIndex:[rowIndex intValue]];
}
- (NSString *)classForSection:(NSInteger)section
{
return [self.sectionToClassMap objectForKey:[NSNumber numberWithInt:section]];
}
#end
When I look at the NSLog data, self.objects is empty. I know this is the reason why data isn't displayed, and would like some advice to sort this out please! Thanks.
I'm following this AppCoda tutorial on implementing Search; however, I'm pulling titles for the table view from Parse and can't get the search function to work. Throws an exception when I start typing in the search:
'Can't use in/contains operator with collection {
buildingLat = "42.726366";
buildingLong = "-84.480642";
buildingTitle = "International Center";
} (not a collection)'
Here's the code for my table view controller:
#import "BuildingsViewController.h"
#import <Parse/Parse.h>
#interface BuildingsViewController ()
#end
#implementation BuildingsViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
[self performSelector:#selector(retrieveBuildings)];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - TableView Setup
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [self.buildingsArray count];
if (tableView == self.searchDisplayController.searchResultsTableView) {
return [self.searchResults count];
} else {
return [self.buildingsArray count];
}
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"buildingsCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
PFObject *tempObject = [self.buildingsArray objectAtIndex:indexPath.row];
cell.textLabel.text = [tempObject objectForKey:#"buildingTitle"];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
if (tableView == self.searchDisplayController.searchResultsTableView) {
cell.textLabel.text = [self.searchResults objectAtIndex:indexPath.row];
} else {
cell.textLabel.text = [tempObject objectForKey:#"buildingTitle"];
}
return cell;
}
#pragma mark - Helper Methods
-(void)retrieveBuildings
{
PFQuery *retrieveBuildings = [PFQuery queryWithClassName:#"buildingsList"];
[retrieveBuildings findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
if (!error) {
self.buildingsArray = [[NSArray alloc] initWithArray:objects];
}
[self.tableView reloadData];
}];
}
- (void)filterContentForSearchText:(NSString*)searchText scope:(NSString*)scope
{
NSPredicate *resultPredicate = [NSPredicate
predicateWithFormat:#"SELF contains[cd] %#",
searchText];
self.searchResults = [self.buildingsArray filteredArrayUsingPredicate:resultPredicate];
}
-(BOOL)searchDisplayController:(UISearchDisplayController *)controller
shouldReloadTableForSearchString:(NSString *)searchString
{
[self filterContentForSearchText:searchString
scope:[[self.searchDisplayController.searchBar scopeButtonTitles]
objectAtIndex:[self.searchDisplayController.searchBar
selectedScopeButtonIndex]]];
return YES;
}
#end
I think you are on the right track...
My understanding is that you are receiving an array of dictionaries, and passing that received array to your declared buildingsArray. This is not the issue. The issue in my understanding is that you are then attempting to retrieve one of the values from one of those dictionaries without the appropriate code.
Your are attempting this process in two locations.
I refer to the code within your cellForRowAtIndexPath method.
As an aside, it is no longer necessary to check for cell == nil, so you can remove the if statement that wraps your cell setter (cell = [[UITableViewCell...).
UPDATE...
The crash in your code when you remove this check for nil is due to the fact that you do not register a reuse identifier for the searchResultsTableView.
To correct your search and data parsing, I recommend that you follow the sample code I have included following.
Add a new property tempMutableArray, and remove the static declaration from cellForRowAtIndexPath and place it between the #import and #interface lines as shown following...
#import <Parse/Parse.h>
static NSString *CellIdentifier = #"buildingsCell"; // relocated static declaration
#interface BuildingsViewController ()
#property (nonatomic, strong) NSMutableArray *tempMutableArray;
#end
// implementation
Then in your viewDidLoad TVC lifecycle method, instantiate the NSMutableArray, and register the UITableViewCell class and CellIdentifier reuse identifier with searchResultsTableView...
- (void)viewDidLoad {
[super viewDidLoad];
//...your other code...
[self setTempMutableArray:[[NSMutableArray alloc] init]];
[self.searchDisplayController.searchResultsTableView registerClass:[UITableViewCell class]
forCellReuseIdentifier:CellIdentifier];
}
...
YOUR NEW REPLACEMENT cellForRowAtIndexPath: METHOD
To properly parse your information from Parse, try the following...
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = nil;
if (tableView == self.searchDisplayController.searchResultsTableView) {
cell = [self.searchDisplayController.searchResultsTableView dequeueReusableCellWithIdentifier:CellIdentifier];
cell.textLabel.text = [self.searchResults objectAtIndex:indexPath.row];
} else {
cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
NSDictionary *tempDict = nil;
NSString *tempString = nil;
tempDict = [self.buildingsArray objectAtIndex:indexPath.row];
tempString = [tempDict objectForKey:#"buildingTitle"];
[cell.textLabel setText:tempString];
}
return cell;
}
You will also need to complete similar in your filterContentForSearchText: method.
YOUR NEW REPLACEMENT filterContentForSearchText: METHOD
- (void)filterContentForSearchText:(NSString*)searchText scope:(NSString*)scope
{
NSPredicate *resultPredicate = nil;
[self.tempMutableArray removeAllObjects];
for (NSDictionary *tempDict in self.buildingsArray) {
NSString *tempString = nil;
tempString = [tempDict objectForKey:#"buildingTitle"];
[self.tempMutableArray addObject:tempString];
}
resultPredicate = [NSPredicate predicateWithFormat:#"SELF contains[cd] %#", searchText];
self.searchResults = [self.tempMutableArray filteredArrayUsingPredicate:resultPredicate];
}
...CONTINUE WITH PREVIOUS RESPONSE
My understanding... what is happening in your code is that your PFQuery returns an NSArray in its completion block. You set your property buildingsArray, also an NSArray, based on this. Your no longer need, as far as I understand, to treat the returned data as a PFObject.
Let me know how you go.
You are trying to apply the NSPredicate on an array of PFObjects so your predicate needs to look like this:
NSPredicate *resultPredicate = [NSPredicate
predicateWithFormat:#"variableNameToSearchOn contains[cd] %#",
searchText];
EDIT:
You can try this:
NSPredicate *resultPredicate = [NSPredicate
predicateWithFormat:#"buildingTitle contains[c] %#",
searchText];
#pragma mark UISearchBarDelegate
-(void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar{
sar.showsCancelButton=YES;
sar.autocorrectionType = UITextAutocorrectionTypeNo;
}
- (BOOL)searchBar:(UISearchBar *)searchBar shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text
{
NSString* newText = [searchBar.text stringByReplacingCharactersInRange:range withString:text];
searchStr = newText;
[self DisplayMatchSearch];
[tblView reloadData];
return YES;
}
-(BOOL)searchBarShouldEndEditing:(UISearchBar *)searchBar{
//write code for requset data from database search.....
sar.showsCancelButton=NO;
[sar resignFirstResponder];
return YES;
}
-(void)searchBarCancelButtonClicked:(UISearchBar *)searchBar{
[self getAlldata];
#try {
[tblBeepUsers reloadData];
}
#catch (NSException * e) {
}
[sar resignFirstResponder];
sar.text=#"";
}
- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar{
searchStr = sar.text;
[sar resignFirstResponder];
[self DisplayMatchSearch];
[tblView reloadData];
}
-(void)DisplayMatchSearch{
if (searchStr && searchStr.length) {
//temp array
arrLocation = [[NSMutableArray alloc] init];
//parsed array self.buildingsArray
for (NSDictionary *dictionary in self.buildingsArray)
{
if ([[dictionary objectForKey:#"name"] rangeOfString:searchStr options:NSCaseInsensitiveSearch].location != NSNotFound) {
[arrLocation addObject:dictionary];
}
}
[tblview reloadData];
}
}
I am pretty new in objective c so hopefully this all make sense.I have followed this video tutorial from YouTube.The program is not working .
You can download the project from this link.Guide me
to make this program functional.
use the following tutorial is the simple way to get the answer and and also u get the sample code in github, the link is http://www.appcoda.com/how-to-add-search-bar-uitableview/
in your view controller.h file
import
#interface RecipeBookViewController : UIViewController <UITableViewDelegate, UITableViewDataSource>
{
NSArray *recipes; //this is used for load the data to table
NSArray *searchResults; //this is used for search the particular name in uitableview
}
#property (nonatomic, strong) UITableView *tableView; //progrmatically allocationg the tableview
.m file
#synthesize tableView; //this is used accessing the name in more than one time
- (void)viewDidLoad
{
[super viewDidLoad];
// Initialize table data
searchResults=[NSArray alloc]init];
recipes = [NSArray arrayWithObjects:#"Egg Benedict", #"Mushroom Risotto", #"Full Breakfast", #"Hamburger", #"Green Tea", #"Thai Shrimp Cake", #"Angry Birds Cake", #"Ham and Cheese Panini", nil];
//create the tableview
tableView =[[UITableView alloc]initWithFrame:CGRectMake(0, 163, 320, 317)];
tableView.delegate=self;
tableView.dataSource=self;
[self. tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:#"cell"];
[self.view addSubview: tableView];
}
//this is for loading the table data
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if (tableView == self.searchDisplayController.searchResultsTableView) {
return [searchResults count];
} else {
return [recipes count];
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *simpleTableIdentifier = #"cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier];
}
if (tableView == self.searchDisplayController.searchResultsTableView) {
cell.textLabel.text = [searchResults objectAtIndex:indexPath.row];
} else {
cell.textLabel.text = [recipes objectAtIndex:indexPath.row];
}
return cell;
}
//this is for search bar delegate method for filtering
- (void)filterContentForSearchText:(NSString*)searchText scope:(NSString*)scope
{
NSPredicate *resultPredicate = [NSPredicate
predicateWithFormat:#"SELF contains[cd] %#",
searchText];
searchResults = [recipes filteredArrayUsingPredicate:resultPredicate];
}
#pragma mark - UISearchDisplayController delegate methods
-(BOOL)searchDisplayController:(UISearchDisplayController *)controller
shouldReloadTableForSearchString:(NSString *)searchString
{
[self filterContentForSearchText:searchString
scope:[[self.searchDisplayController.searchBar scopeButtonTitles]
objectAtIndex: [self.searchDisplayController.searchBar
selectedScopeButtonIndex]]];
return YES;
}
finally add the one search bar display controller only in top on the view
- (void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar; // called when text starts editing
{
if (searching)
{
searching=YES;
letsUserSelectRow=YES;
}
else
{
searching=NO;
letsUserSelectRow=YES;
}
// self.tbl_searchtable.scrollEnabled=NO;
}
- (void)searchBarCancelButtonClicked:(UISearchBar *) searchBar
{
searching = NO;
letsUserSelectRow = YES;
searchBar.text = #"";
[searchBar resignFirstResponder];
[self.tbl_searchuser reloadData];
}
-(NSIndexPath *)tableView :(UITableView *)theTableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if(letsUserSelectRow)
return indexPath;
else
return nil;
}
- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText; // called when text changes (including clear)
{
_tbl_searchuser.hidden=FALSE;
[copylistofitem removeAllObjects];
if([searchText length] > 0)
{
searching = YES;
letsUserSelectRow = YES;
self.tbl_searchuser.scrollEnabled = YES;
[self searchtableview];
}
else
{
searching = NO;
letsUserSelectRow= NO;
[_searchbar resignFirstResponder];
//self.tbl_searchtable.scrollEnabled = NO;
}
[copylistofitem retain];
[self.tbl_searchuser reloadData];
}
- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar; // called when keyboard search button pressed
{
[self hide];
//[self searchtableview];
}
-(void)searchtableview
{
_tbl_searchuser.frame=CGRectMake(0, 65, 320, 140);
NSString *searchText = _searchbar.text;
NSLog(#"%#",array_allusers);
for(int l = 0; l < [array_allusers count]; l++)
{
NSString *tempstr = [[array_allusers objectAtIndex:l] objectForKey:#"username"];
NSRange rngstr = [tempstr rangeOfString:searchText options:(NSAnchoredSearch | NSCaseInsensitiveSearch)];
if(rngstr.length > 0)
{
[copylistofitem addObject:[array_allusers objectAtIndex:l]];
[copylistofitem retain];
}
}
NSLog(#"%#",copylistofitem);
NSSortDescriptor *sort = [NSSortDescriptor sortDescriptorWithKey:#"username" ascending:YES];
[copylistofitem sortUsingDescriptors:[NSArray arrayWithObject:sort]];
[_tbl_searchuser reloadData];
}
-(void)hide
{
[_searchbar resignFirstResponder];
_tbl_searchuser.frame=CGRectMake(0, 65, 320, 274);
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if (searching && [_searchbar.text length] > 0)
return [copylistofitem count];
else
return yourarray;
}
NSMutableArray *copylistofitem;
BOOL searching;
BOOL letsUserSelectRow;
hi everyone
i am using the code in below without using storyboard and its run ok, but its crash when i write the second letter of searching word.
anyone can help me
in ViewController.h
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController <UITableViewDataSource, UITableViewDelegate>
#property (nonatomic, strong) IBOutlet UITableView *tableView;
#property (retain, nonatomic) IBOutlet UILabel *nameLabel;
#end
in ViewController.m
#import "ViewController.h"
#import "DetailController.h"
#interface ViewController ()
#end
#implementation ViewController {
NSArray *peopleName;
NSArray *searchResult;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
peopleName = [[NSArray alloc] initWithObjects:#"john", #"Waseem", #"Bruce", #"Ammar", #"Londol", nil];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void)dealloc {
[_nameLabel release];
[super dealloc];
}
//
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if (tableView == self.searchDisplayController.searchResultsTableView) {
return [searchResult count];
} else {
return [peopleName count];
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *identifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier] autorelease];
}
if (tableView == self.searchDisplayController.searchResultsTableView) {
cell.textLabel.text = [searchResult objectAtIndex:indexPath.row];
} else {
cell.textLabel.text = [peopleName objectAtIndex:indexPath.row];
}
return cell;
}
#pragma mark - UISearchDisplayController delegate methods
- (void)filterContentForSearchText:(NSString*)searchText scope:(NSString*)scope
{
NSPredicate *resultPredicate = [NSPredicate
predicateWithFormat:#"SELF contains[cd] %#",
searchText];
searchResult = [peopleName filteredArrayUsingPredicate:resultPredicate];
}
-(BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString
{
[self filterContentForSearchText:searchString
scope:[[self.searchDisplayController.searchBar scopeButtonTitles]
objectAtIndex:[self.searchDisplayController.searchBar
selectedScopeButtonIndex]]];
return YES;
}
#end
its crash and show me this
cell.textLabel.text = [searchResult objectAtIndex:indexPath.row];
(lldb)
Thread 1:EXC_BAD_ACCESS (code=2, address=0x8)
Used the below code snippet:
#pragma mark - UISearchDisplayController delegate methods
- (void)filterContentForSearchText:(NSString*)searchText scope:(NSString*)scope
{
NSPredicate *resultPredicate = [NSPredicate
predicateWithFormat:#"SELF contains[cd] %#",
searchText];
[searchResult release];
searchResult = [peopleName filteredArrayUsingPredicate:resultPredicate]retain];
}