Parse SDK for iOS; Using UISearchBar on UITableView - ios

I'm retrieving data from parse and put it the tableview but when I'm trying to also add a searchbar I don't know how can I manage it. What should I do on tableView:cellForRowAtIndexPath: method instead of NSLog(#"do something!!");
My code is below and thanks for any help.
retrieve from parse code is below
- (void) retrieveFromParse {
PFQuery *retrieveName = [PFQuery queryWithClassName:#"pFihrist"];
[retrieveName findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
if (!error) {
nameArray = [[NSMutableArray alloc] initWithArray:objects];
}
[tableView reloadData];
}];
}
UITableView Delegate code is below
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if (self.tableView == self.searchDisplayController.searchResultsTableView) {
return [searchResults count];
} else {
return [nameArray count];
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"fCell";
FihristCell *cell = (FihristCell *)[self.tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[FihristCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
if (tableView == self.tableView) {
PFObject *tempObject = [nameArray objectAtIndex:indexPath.row];
cell.cellProfName.text = [tempObject objectForKey:#"pName"];
} else {
NSLog(#"do something!!");
}
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(#"cell tapped");
}
search methods code is below
- (void)filterContentForSearchText:(NSString*)searchText scope:(NSString*)scope
{
NSPredicate *resultPredicate = [NSPredicate predicateWithFormat:#"name contains[c] %#", searchText];
searchResults = [nameArray filteredArrayUsingPredicate:resultPredicate];
}
-(BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString
{
[self filterContentForSearchText:searchString
scope:[[self.searchDisplayController.searchBar scopeButtonTitles]
objectAtIndex:[self.searchDisplayController.searchBar
selectedScopeButtonIndex]]];
return YES;
}

First Register the Cell to display you searched items
You have to register the cell to searchdisplaycontroller as well.
Important: You must register a class or nib file using the registerNib:forCellReuseIdentifier: or registerClass:forCellReuseIdentifier: method before calling this method.
in View did load
If you are Creating cell in code
[self.searchDisplayController.searchResultsTableView registerClass:[TableViewCell class]
forCellReuseIdentifier:#"IdentifierForCell"];
If you are Creating cell in nib
[self.searchDisplayController.searchResultsTableView registerNib:[UINib nibWithNibName:#"CellNibName" bundle:nil]
forCellWithReuseIdentifier:#"IdentifierForCell"];
2. Deque corresponding cell to search display controller table with identifier
FihristCell *cell = (FihristCell *)[self.searchDisplayController.searchResultsTableView dequeueReusableCellWithIdentifier:CellIdentifier];
3. configure that cell to display instead of NSLog

Related

UISearchDisplayController - results exists but are not displayed

I have strange problem with UISearchDisplayController.
My code is following:
numberOfRowsInSection:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if ([[self searchDisplayController] isActive])
{
return [self.itemsFound count];
} else {
return [self.items count];
}
return [self.items count];
}
cellForRowAtIndexPath:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
FavouriteTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (!cell)
{
cell = [[FavouriteTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
Facilities *f = nil;
if ([[self searchDisplayController] isActive])
{
f = [self.itemsFound objectAtIndex:indexPath.row];
} else {
f = [self.items objectAtIndex:indexPath.row];
}
[cell.favouriteButton addTarget:self action:#selector(toggleFavourite:) forControlEvents:UIControlEventTouchUpInside];
[cell.titleLabel setText:f.name];
return cell;
}
next:
- (void)filterContentForSearchText:(NSString*)searchText scope:(NSString*)scope
{
NSPredicate *resultPredicate = [NSPredicate predicateWithFormat:#"name contains[c] %#",searchText];
self.itemsFound = [self.items filteredArrayUsingPredicate:resultPredicate];
}
shouldReloadTableForSearchString:
- (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString {
self.itemsFound = nil;
[self filterContentForSearchText:searchString
scope:[[self.searchDisplayController.searchBar scopeButtonTitles]
objectAtIndex: [self.searchDisplayController.searchBar
selectedScopeButtonIndex]]];
return YES;
}
My table:
If I type letters, which are on the list:
Results exist but are not showing on a list.
On next picture there are no results and the screen shows correct info.
I have no idea why I can not show results on second screen while results are (displayed on console).
Do you have any idea ?
Thanks for your time.

display search result in table view in objective-c

I've created a table view with search bar in my View Controller, but the table view doesn't show the search result.
This is how my code working. First i create an Array to hold data >> display the array data in table view >> using search bar to filter the table view.
Here is my code :
- (void)viewDidLoad {
[super viewDidLoad];
self.inventoryarray =[[NSArray alloc] initWithObjects: #"apple",#"samsung",#"HTC",#"LG",#"Sony",#"Motorola",#"Nexus",#"Asus" ,nil];
self.searchresult =[[NSArray alloc]init];
// Do any additional setup after loading the view, typically from a nib.
}
#pragma table View methods
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
if (tableView == self.searchDisplayController.searchResultsTableView) {
return [self.searchresult count];
} else {
return [self.inventoryarray count];
}
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *simpleTableIdentifier = #"CellID";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier];
}
if (tableView == self.searchDisplayController.searchResultsTableView) {
cell.textLabel.text = [self.searchresult objectAtIndex:indexPath.row];
} else {
cell.textLabel.text = [self.inventoryarray objectAtIndex:indexPath.row];
}
return cell;
}
#pragma search methods
-(void) filterContentForSearchText:(NSString *)searchText scope:(NSString *)scope
{
NSPredicate *resultPredicate = [NSPredicate predicateWithFormat:#"SELF contains[cd] %#", searchText];
self.searchresult = [self.inventoryarray filteredArrayUsingPredicate:resultPredicate];
}
-(BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString {
[self filterContentForSearchText:searchString scope:[[self.searchDisplayController.searchBar scopeButtonTitles] objectAtIndex:[self.searchDisplayController.searchBar selectedScopeButtonIndex]]] ;
return YES;
}
you forget to refesh data on table
-(void) filterContentForSearchText:(NSString *)searchText scope: (NSString *)scope
{
NSPredicate *resultPredicate = [NSPredicate
predicateWithFormat:#"SELF contains[cd] %#",
searchText];
self.searchresult = [self.inventoryarray filteredArrayUsingPredicate:resultPredicate];
// you forget to reload Data
[self.searchDisplayController.searchResultsTableView reloadData];
// else use
[yourtableView reloadData];
}
suggestion : UISearchDisplayController is deprecated, use UISearchController on onwards, for tutorial
You need to only [tableView reloadData]; in last of filterContentForSearchText method.
if you wan't to use UISearchController then...
- 'UISearchDisplayController' is deprecated: first deprecated in iOS 8.0 - UISearchDisplayController has been replaced with UISearchController
if you don't want to use UISearchController then use below method:
- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText {} and reload tableview.

Having trouble showing results of UISearchBar

I am new to iOS development and trying to get help with search result. Everything is working fine but when I search a word, it doesn't show the result so I will be over thanks for your help.. Here is the code..
- (void)viewDidLoad
{
[super viewDidLoad];
mytableview.delegate = self;
mytableview.dataSource = self;
SearchBar.delegate = self;
titleArray = [[NSMutableArray alloc] initWithObjects:#"Arora town",#"Domino pizza ",#"thai hunt",nil];
subtitleArray = [[NSMutableArray alloc] initWithObjects:#"wX<w (rHR< cg)",#"o;vDRuwkR(vXw>csK;cHed;o;wkRtd.tCd)<*kRuhRto; (vXw>urXur.tylR)<o;vDRxl.",nil];
}
here is cellForRowAtIndexPath
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath: (NSIndexPath *)indexPath
{
static NSString *cellidentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellidentifier forIndexPath:indexPath];
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 = [titleArray objectAtIndex:indexPath.row];
}
return cell;
}
- (void)filterContentForSearchText:(NSString*)searchText scope:(NSString*)scope
{
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"SELF beginswith[c] %#", searchText];
self.searchResults = [self.array filteredArrayUsingPredicate:predicate];
}
-(BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString
{
[self filterContentForSearchText:searchString
scope:[[self.searchDisplayController.searchBar scopeButtonTitles]
objectAtIndex:[self.searchDisplayController.searchBar
selectedScopeButtonIndex]]];
return YES;
}
Try This i Have tested.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if(tableView==self.searchDisplayController.searchResultsTableView)
return _results.count;
else
return _countryNames.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *identifier=#"Cell";
UITableViewCell *cell;
cell=[tableView dequeueReusableCellWithIdentifier:identifier];
if(cell==nil)
{
cell=[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier];
}
if (tableView == self.searchDisplayController.searchResultsTableView) {
cell.textLabel.text = [_results objectAtIndex:indexPath.row];
} else {
cell.textLabel.text = [_countryNames objectAtIndex:indexPath.row];
}
return cell;
}
- (void)filterContentForSearchText:(NSString*)searchText scope:(NSString*)scope
{
NSPredicate *resultPredicate = [NSPredicate
predicateWithFormat:#"SELF contains[cd] %#",
searchText];
NSLog(#"%#",scope);
_results = (NSMutableArray *)[_countryNames filteredArrayUsingPredicate:resultPredicate];
}
- (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString
{
[self filterContentForSearchText:searchString
scope:[[self.searchDisplayController.searchBar scopeButtonTitles]
objectAtIndex:[self.searchDisplayController.searchBar
selectedScopeButtonIndex]]];
return YES;
}
in viewDidLoad
initialize
_results=[[NSMutableArray alloc]init];
_countryNames=[[NSMutableArray alloc] initWithObjects:#"India",#"Pakistan",#"West Indies",#"Zimbabwe", nil];
connect search bar delegate from storyboard.

Repopulating UITableView after search

I'm using single NSFetchedResultController to populate both self.tableView and UISearchDisplayControler.tableView. After using search bar and dismissing it if I select any row in the self.tableView I get this error:
Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[__NSArrayM objectAtIndex:]: index 0 beyond bounds for empty array'
I guess that somewhere I miss reloading data but I have no clue where?
Here are some methods which I use for populating both tabble views:
#pragma mark - Table View
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Count sections in FRC
return [[self.groupsFRC sections] count];
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Count groups in each section of FRC
return [[[self.groupsFRC sections] objectAtIndex:section] numberOfObjects];
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
// Get reusable cell
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"GroupCell"];
// If there isn't any create new one
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"GroupCell"];
}
Group *group = [self.groupsFRC objectAtIndexPath:indexPath];
cell.textLabel.text = group.name;
// Checking if group has been selected earlier
if ([self.selectedGroups containsObject:#{#"name" : group.name, #"id" : group.cashID}]) {
[cell setAccessoryType:UITableViewCellAccessoryCheckmark];
} else {
[cell setAccessoryType:UITableViewCellAccessoryNone];
}
return cell;
}
// Adding checkmark to selected cell
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *selectedCell = [tableView cellForRowAtIndexPath:indexPath];
Group *group = [self.groupsFRC objectAtIndexPath:indexPath];
// Checking if selected cell has accessory view set to checkmark and add group to selected groups array
if (selectedCell.accessoryType == UITableViewCellAccessoryNone)
{
selectedCell.accessoryType = UITableViewCellAccessoryCheckmark;
[self.selectedGroups addObject:#{#"name" : group.name, #"id" : group.cashID}];
NSLog(#"%#", self.selectedGroups);
}
else if (selectedCell.accessoryType == UITableViewCellAccessoryCheckmark)
{
selectedCell.accessoryType = UITableViewCellAccessoryNone;
[self.selectedGroups removeObject:#{#"name" : group.name, #"id" : group.cashID}];
NSLog(#"%#", self.selectedGroups);
}
// Hiding selection with animation for nice and clean effect
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}
#pragma mark - Filtering
- (void)filterContentForSearchText:(NSString*)searchText scope:(NSString*)scope
{
NSPredicate *resultPredicate = [NSPredicate predicateWithFormat:#"SELF.name contains[c] %#", searchText];
self.groupsFRC = [Group MR_fetchAllSortedBy:#"caseInsensitiveName"
ascending:YES
withPredicate:resultPredicate
groupBy:#"sectionLetter"
delegate:self];
}
-(BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString
{
[self filterContentForSearchText:searchString
scope:[[self.searchDisplayController.searchBar scopeButtonTitles] objectAtIndex:[self.searchDisplayController.searchBar selectedScopeButtonIndex]]];
return YES;
}
-(void)searchDisplayController:(UISearchDisplayController *)controller didHideSearchResultsTableView:(UITableView *)tableView
{
// Setting FRC to fetch original table view data
self.groupsFRC = [Group MR_fetchAllSortedBy:#"caseInsensitiveName"
ascending:YES
withPredicate:nil
groupBy:#"sectionLetter"
delegate:self];
}
Okey, I finally get over this problem but with skipping UISearchDisplayDelegate and implementing this only using UISearchBarDelegate. Here is the code:
-(void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText
{
if (searchText.length > 0) {
resultPredicate = [NSPredicate predicateWithFormat:#"SELF.name contains[c] %#", searchText];
} else {
resultPredicate = nil;
}
[self refreshFRC];
}
-(void)searchBarCancelButtonClicked:(UISearchBar *)searchBar
{
resultPredicate = nil;
[self refreshFRC];
}
- (void)refreshFRC {
if (resultPredicate != nil) {
self.groupsFRC = [Group MR_fetchAllSortedBy:#"caseInsensitiveName"
ascending:YES
withPredicate:resultPredicate
groupBy:#"sectionLetter"
delegate:self];
} else {
self.groupsFRC = [Group MR_fetchAllSortedBy:#"caseInsensitiveName"
ascending:YES
withPredicate:nil
groupBy:#"sectionLetter"
delegate:self];
[self.tableView reloadData];
}
}

Trying to understand what is going on at didselectrowatindexpath. App crashes with message index 1 beyond bounds [0 .. 0]'

I'm trying to understand what is going on with my code.
App is crashing when I'm selecting one of the items of my array. Basically, she user selects one row it should open a new tableview with data for that selected row, but it is only working for one row, I'm guessing my array has only one result when I filter (search bar), and when I click object at index 1 it crashes. But that's just a guess, I couldn't fix it.
I have two NSArrays.
#implementation BuscaDadosNoBanco
{
NSArray *searchResults;
NSArray *todosUsuarios;
}
Here is the code for the table:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if (tableView == self.searchDisplayController.searchResultsTableView) {
return [searchResults count];
} else {
return [todosUsuarios count];
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *simpleTableIdentifier = #"RecipeCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier];
}
cell.textLabel.text = [searchResults objectAtIndex:indexPath.row];
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if (tableView == self.searchDisplayController.searchResultsTableView) {
NSLog(#"%#", searchResults);
NSLog(#"%#", _arrayComDados);
[self performSegueWithIdentifier: #"segueDetalhesUsuario" sender: self];
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:#"segueDetalhesUsuario"]) {
DetalhesUsuario *destViewController = segue.destinationViewController;
NSIndexPath *indexPath = nil;
if ([self.searchDisplayController isActive]) {
indexPath = [self.searchDisplayController.searchResultsTableView indexPathForSelectedRow];
Usuario *usuario = [[Usuario alloc] init];
[usuario recuperaDadosUsuario:_arrayComDados eEmail:[searchResults objectAtIndex:indexPath.row]];
destViewController.dadosUsuario = usuario;
} else {
indexPath = [self.tableView indexPathForSelectedRow];
destViewController.dadosUsuario = [todosUsuarios objectAtIndex:indexPath.row];
}
}
}
- (void)filterContentForSearchText:(NSString*)searchText scope:(NSString*)scope
{
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"usuario.username contains [cd] %#", searchText];
NSArray *filtroUsuario = [_arrayComDados filteredArrayUsingPredicate:predicate];
searchResults = [filtroUsuario valueForKeyPath:#"#distinctUnionOfObjects.usuario.username"];
NSLog(#"%#", searchResults);
}
#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;
}
- (BOOL)searchDisplayController:(UISearchDisplayController *)controller
shouldReloadTableForSearchScope:(NSInteger)searchOption
{
[self filterContentForSearchText:[self.searchDisplayController.searchBar text]
scope:[[self.searchDisplayController.searchBar scopeButtonTitles]
objectAtIndex:searchOption]];
return YES;
}
Whenever I type the right letter in the search bar, the log shows one email string like "blabla#bla.com". I have two items in my array, one is working when I select it populates the next tableview correctly, but when I try the other one, although it shows the correct email in the log, the app crashes with the message: -[__NSArrayI objectAtIndex:]: index 1 beyond bounds [0 .. 0].
Please let me know if you need any other information. I really need help with this.
Thanks
Issue in Your code!
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
if (tableView == self.searchDisplayController.searchResultsTableView) {
return [searchResults count];
} else {
return [todosUsuarios count];
}
}
here You chech which array use but when You create cell You do not check which array should be used
cell.textLabel.text = [searchResults objectAtIndex:indexPath.row];
So, You can get situation when count of rows comes from todosUsuarios but elements You trying get from searchResults

Resources