How to show UISearchbar bar only in tableview not on UINavigationbar in objective c - objective-c

I am new in ios and I am facing problem regarding to UISearchbar. I have done code like this
.h
IBOutlet UITableView *table;
NSArray *recipes;
NSArray *searchResults;
.m
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
recipes = [NSArray arrayWithObjects:#"Egg Benedict", #"Mushroom Risotto", #"Full Breakfast", #"Hamburger", #"Ham and Egg Sandwich", #"Creme Brelee", #"White Chocolate Donut", #"Starbucks Coffee", #"Vegetable Curry", #"Instant Noodle with Egg", #"Noodle with BBQ Pork", #"Japanese Noodle with Pork", #"Green Tea", #"Thai Shrimp Cake", #"Angry Birds Cake", #"Ham and Cheese Panini", nil];
}
- (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 *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
}
if (tableView == self.searchDisplayController.searchResultsTableView) {
cell.textLabel.text = [searchResults objectAtIndex:indexPath.row];
} else {
cell.textLabel.text = [recipes objectAtIndex:indexPath.row];
}
return cell;
}
- (void)filterContentForSearchText:(NSString*)searchText scope:(NSString*)scope
{
NSPredicate *resultPredicate = [NSPredicate
predicateWithFormat:#"SELF contains[cd] %#",
searchText];
searchResults = [recipes filteredArrayUsingPredicate:resultPredicate];
}
-(BOOL)searchDisplayController:(UISearchController *)controller shouldReloadTableForSearchString:(NSString *)searchString
{
[self filterContentForSearchText:searchString
scope:[[self.searchDisplayController.searchBar scopeButtonTitles]
objectAtIndex:[self.searchDisplayController.searchBar
selectedScopeButtonIndex]]];
return YES;
}
But it shows me search bar on navigation bar
But I need to show it on the UItableView itself. Like this in Image
Thanks in advance

I have use code to search from 4 mutable array...
- (void)viewDidLoad {
[super viewDidLoad];
[searchtxt addTarget:self action:#selector(textFieldDidChangeClose:) forControlEvents:UIControlEventEditingChanged];
searchtxt.delegate=self;
}
#pragma mark - Seach Button...
-(void)textFieldDidChangeClose:(UITextField *)textField
{
searchTextString=textField.text;
[self updateSearchArray:searchTextString];
}
-(void)updateSearchArray:(NSString *)searchText
{
if(searchText.length==0)
{
isFilter=NO;
[table reloadData];
}
else{
isFilter=YES;
searchArray=[[NSMutableArray alloc]init];
searchArrayId=[[NSMutableArray alloc] init];
searchArraystatus=[[NSMutableArray alloc] init];
searchArraydescription=[[NSMutableArray alloc] init];
for(NSString *string in idarray){
NSRange stringRange=[string rangeOfString:searchText options:NSCaseInsensitiveSearch];
if(stringRange.location !=NSNotFound){
[searchArray addObject:string];
NSInteger index = [idarray indexOfObject:string];
[searchArraystatus addObject:[shortnamearray objectAtIndex:index]];
[searchArraydescription addObject:[descarray objectAtIndex:index]];
[searchArrayId addObject:[complaintidArray objectAtIndex:index]];
}
}
[table reloadData];
}
}
#pragma mark - TableView Delegate
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if(isFilter)
{
return [searchArray count];
}
else
{
return [idarray count];
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *STI=#"STI";
IBTClosedComplaintCell *cell = (IBTClosedComplaintCell *)[tableView dequeueReusableHeaderFooterViewWithIdentifier:STI];
if (cell == nil)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"IBTClosedComplaintCell" owner:self options:nil];
cell = [nib objectAtIndex:0];
cell.accessoryType=UITableViewCellAccessoryNone;
}
if(isFilter)
{
cell.Complaintnamelbl.text=[NSString stringWithFormat:#"%#",[searchArray objectAtIndex:indexPath.row]];
cell.statuslbl.text = [NSString stringWithFormat:#"%#",[searchArraystatus objectAtIndex:indexPath.row]];
cell.descriptiolbl.text=[NSString stringWithFormat:#"%#",[searchArraydescription objectAtIndex:indexPath.row]];
cell.complaintidlbl.text = [NSString stringWithFormat:#"%#",[searchArrayId objectAtIndex:indexPath.row]];
}
else
{
cell.Complaintnamelbl.text=[idarray objectAtIndex:indexPath.row];
cell.statuslbl.text=[shortnamearray objectAtIndex:indexPath.row];
cell.descriptiolbl.text=[descarray objectAtIndex:indexPath.row];
cell.complaintidlbl.text=[NSString stringWithFormat:#"%#",[complaintidArray objectAtIndex:indexPath.row]];
}
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
IBTClosedNextScreen *next =[[IBTClosedNextScreen alloc] initWithNibName:#"IBTClosedNextScreen" bundle:nil];
[self.navigationController pushViewController:next animated:YES];
if(isFilter)
{
str1=[NSString stringWithFormat:#"%#",[searchArrayId objectAtIndex:indexPath.row]];
NSLog(#"String =%#",str1);
next.str =str1;
}
else
{
str1=[NSString stringWithFormat:#"%#",[self.complaintidArray objectAtIndex:indexPath.row]];
NSLog(#"String =%#",str1);
next.str =str1;
}
}

Related

Hide the autocomplete Tableview when text field is empty

The following code will generate a custom autocomplete Table View autocompleteTableView below my text field txtActivity. How do I hide the Table View when text field is empty.
- (void)viewDidLoad
{
[super viewDidLoad];
self.txtActivity.delegate = self;
[self cofigureAutoComTableView];
}
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)rangereplacementString:(NSString *)string
{
autocompleteTableView.hidden = NO;
NSString *substring = [NSString stringWithString:textField.text];
substring = [substring stringByReplacingCharactersInRange:range withString:string];
[self searchAutocompleteEntriesWithSubstring:substring];
return YES;
}
- (void)searchAutocompleteEntriesWithSubstring:(NSString *)substring
{
autocompleteMArray = [[NSMutableArray alloc] init];
[autocompleteMArray removeAllObjects];
for(NSString *curString in sCategory) { //**** sCategory is a mutable array generated in another method not shown ****
NSRange substringRange = [curString rangeOfString:substring];
if (substringRange.length > 0) {
[autocompleteMArray addObject:curString];
}
}
NSLog(#"*******The autocompleteMArray : %# ", autocompleteMArray);
[autocompleteTableView reloadData];
}
-(void)cofigureAutoComTableView
{
autocompleteTableView = [[UITableView alloc] initWithFrame:CGRectMake(self.txtActivity.frame.origin.x-10,self.txtActivity.frame.origin.y+32,self.txtActivity.frame.size.width, 120) style:UITableViewStylePlain];
autocompleteTableView.delegate = self;
autocompleteTableView.dataSource = self; //**** Setting this to self, is it correct???
autocompleteTableView.scrollEnabled = YES;
autocompleteTableView.hidden = YES;
[self.view addSubview:autocompleteTableView];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return autocompleteMArray.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellIdentifier = #"cellIdentifier";
UITableViewCell *cell = [self.autocompleteTableView dequeueReusableCellWithIdentifier:cellIdentifier];
if(cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
}
cell.textLabel.text = [autocompleteMArray objectAtIndex:indexPath.row];
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath (NSIndexPath *)indexPath;
{
//**** NOT DETECTING *******
NSLog(#"Selected Cell %#", [autocompleteMArray objectAtIndex:indexPath.row]);
}
If substringRange length is 0 then assign sCategory array to autocompleteMArray and reload the tableview.
- (void)searchAutocompleteEntriesWithSubstring:(NSString *)substring
{
autocompleteMArray = [[NSMutableArray alloc] init];
[autocompleteMArray removeAllObjects];
if ([substring length] == 0)
{
for(NSString *curString in sCategory)
{ //**** sCategory is a mutable array generated in another method not shown ****
NSRange substringRange = [curString rangeOfString:substring];
if (substringRange.length > 0)
{
[autocompleteMArray addObject:curString];
}
}
}
else
{
autocompleteMArray = sCategory;
}
NSLog(#"*******The autocompleteMArray : %# ", autocompleteMArray);
[autocompleteTableView reloadData];
}
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
if([[NSString stringWithFormat:#"%#%#",textField.text,string] isEqualToString:#""]) {
autocompleteTableView.hidden = YES;
} else {
autocompleteTableView.hidden = range.location == 0 ? YES : NO;
NSString *substring = [NSString stringWithString:textField.text];
substring = [substring stringByReplacingCharactersInRange:range withString:string];
[self searchAutocompleteEntriesWithSubstring:substring];
}
return YES; }

Search bar in tableview using objective c with parse database

I've been following a tutorial teaching how to make a tableview with a search bar. I got this to work without problems, but now I learned to make the same tableview but instead of local arrays, I've been getting my data from parse as PFObjects.
I then tried to take the search bar and implant it in my new tableview which uses parse. I can't get this to work. Following the tutorial with the search bar they are using simple arrays stored locally..
Can anyone point me in the right direction of how to use a search bar in a tableview that gets its data from a parse database?
This is my code that works with my tableview that does NOT use parse.
#implementation RecipeBookViewController {
NSArray *recipes;
NSArray *searchResults;
}
#synthesize tableView = _tableView;
- (void)viewDidLoad
{
[super viewDidLoad];
// Initialize table data
recipes = [NSArray arrayWithObjects:#"Egg Benedict", #"Mushroom Risotto",
#"Full Breakfast", #"Hamburger", #"Ham and Egg Sandwich", #"Creme Brelee",
nil];
}
- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
}
- (BOOL)shouldAutorotateToInterfaceOrientation:
(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}
- (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 = #"RecipeCell";
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;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:
(NSIndexPath
- *)indexPath
{
if (tableView == self.searchDisplayController.searchResultsTableView) {
[self performSegueWithIdentifier: #"showRecipeDetail" sender: self];
}
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:#"showRecipeDetail"]) {
RecipeDetailViewController *destViewController =
segue.destinationViewController;
NSIndexPath *indexPath = nil;
if ([self.searchDisplayController isActive]) {
indexPath = [self.searchDisplayController.searchResultsTableView
indexPathForSelectedRow];
destViewController.recipeName = [searchResults
objectAtIndex:indexPath.row];
} else {
indexPath = [self.tableView indexPathForSelectedRow];
destViewController.recipeName = [recipes objectAtIndex:indexPath.row];
}
}
}
- (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;
}
And this is my tableview which get its data from my parse database:
#implementation RecipeBookViewController {
}
- (id)initWithCoder:(NSCoder *)aCoder
{
self = [super initWithCoder:aCoder];
if (self) {
// Custom the table
// The className to query on
self.parseClassName = #"Recipe";
// 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 = NO;
// The number of objects to show per page
//self.objectsPerPage = 10;
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(refreshTable:)
name:#"refreshTable"
object:nil];
}
- (void)refreshTable:(NSNotification *) notification
{
// Reload the recipes
[self loadObjects];
}
- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
[[NSNotificationCenter defaultCenter] removeObserver:self name:#"refreshTable"
object:nil];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:
(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}
- (PFQuery *)queryForTable
{
PFQuery *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;
}*/
// [query orderByAscending:#"name"];
return query;
}
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:
(NSIndexPath *)indexPath object:(PFObject *)object
{
static NSString *simpleTableIdentifier = #"RecipeCell";
UITableViewCell *cell = [tableView
dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:simpleTableIdentifier];
}
// Configure the cell
PFFile *thumbnail = [object objectForKey:#"imageFile"];
PFImageView *thumbnailImageView = (PFImageView*)[cell viewWithTag:100];
thumbnailImageView.image = [UIImage imageNamed:#"placeholder.jpg"];
thumbnailImageView.file = thumbnail;
[thumbnailImageView loadInBackground];
UILabel *nameLabel = (UILabel*) [cell viewWithTag:101];
nameLabel.text = [object objectForKey:#"name"];
UILabel *prepTimeLabel = (UILabel*) [cell viewWithTag:102];
prepTimeLabel.text = [object objectForKey:#"prepTime"];
return cell;
}
- (void)tableView:(UITableView *)tableView commitEditingStyle:
(UITableViewCellEditingStyle)editingStyle
forRowAtIndexPath:(NSIndexPath*) indexPath
{
// Remove the row from data model
PFObject *object = [self.objects objectAtIndex:indexPath.row];
[object deleteInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
[self refreshTable:nil];
}];
}
- (void) objectsDidLoad:(NSError *)error
{
[super objectsDidLoad:error];
NSLog(#"error: %#", [error localizedDescription]);
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:#"showRecipeDetail"]) {
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
RecipeDetailViewController *destViewController =
segue.destinationViewController;
PFObject *object = [self.objects objectAtIndex:indexPath.row];
Recipe *recipe = [[Recipe alloc] init];
recipe.name = [object objectForKey:#"name"];
recipe.imageFile = [object objectForKey:#"imageFile"];
recipe.prepTime = [object objectForKey:#"prepTime"];
recipe.ingredients = [object objectForKey:#"ingredients"];
destViewController.recipe = recipe;
}
}

Parse search table not returning correct results

I am using parse as back-end for my app. I have found a few different methods to implement searchbar feature using a Parse tableview. This idea I found from Parse archives shows all objects on initial view and refresh, but when I search it does not return the correct results. If I type one letter "a" it returns some objects containing "a" but if I type more letters or and actual word that I know should be found it returns a blank table. It is also giving a warning when searching: A long-running Parse operation is being executed on the main thread. I have been working and researching this for a few weeks and can't get past this point. See code for implementation file.
#import "RecipeBookViewController.h"
#import "SearchedResultCell.h"
#import "RecipeDetailViewController.h"
#import "HotelViewController.h"
#import "Recipe.h"
static NSString *const NothingFoundCellIdentifier = #"NothingFoundCell";
#interface RecipeBookViewController ()
#end
#implementation RecipeBookViewController {
}
#synthesize searchedBar;
#synthesize searchResults;
#synthesize recipesTable;
- (id)initWithCoder:(NSCoder *)aCoder
{
self = [super initWithCoder:aCoder];
if (self) {
// Custom the table
// The className to query on
self.parseClassName = #"Recipe";
// 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 = NO;
// The number of objects to show per page
//self.objectsPerPage = 10;
}
return self;
}
- (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.
}
#pragma mark - UIViewController
- (void)viewDidLoad
{
[super viewDidLoad];
UINib *cellNib = [UINib nibWithNibName:NothingFoundCellIdentifier bundle:nil];
[self.tableView registerNib:cellNib forCellReuseIdentifier:NothingFoundCellIdentifier];
[self.searchedBar becomeFirstResponder];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(refreshTable:)
name:#"refreshTable"
object:nil];
}
- (void)refreshTable:(NSNotification *) notification
{
// Reload the recipes
[self loadObjects];
}
- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
[[NSNotificationCenter defaultCenter] removeObserver:self name:#"refreshTable" object:nil];
}
#pragma mark - UISearchBarDelegate
- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar
{
[searchResults removeAllObjects];
[self.searchedBar resignFirstResponder];
searchResults = [NSMutableArray arrayWithCapacity:10];
//#warning Put your ClassName here
PFQuery *query = [PFQuery queryWithClassName:#"Recipe"];
//#warning put key that you want to search here
[query whereKey:#"name" containsString:searchedBar.text];
NSArray *results = [query findObjects];
[searchResults addObjectsFromArray:results];
//#warning put your key here
[query orderByAscending:#"name"];
//[self queryForTable];
[self loadObjects];
}
#pragma mark - PFQueryTableViewController
- (void)objectsWillLoad {
[super objectsWillLoad];
// This method is called before a PFQuery is fired to get more objects
}
- (void) objectsDidLoad:(NSError *)error
{
[super objectsDidLoad:error];
NSLog(#"error: %#", [error localizedDescription]);
}
#pragma mark - Query
- (PFQuery *)queryForTable
{
PFQuery *query;
if (self.searchResults == 0) {
query = [PFQuery queryWithClassName:self.parseClassName];
} else {
query = [PFQuery queryWithClassName:self.parseClassName];
NSString *searchThis = [searchedBar.text lowercaseString];
//#warning key you wanted to search here
[query whereKeyExists:#"name"];
[query whereKey:#"name" containsString:searchThis];
}
[query orderByAscending:#"name"];
// If Pull To Refresh is enabled, query against the network by default.
if (self.pullToRefreshEnabled) {
query.cachePolicy = kPFCachePolicyNetworkOnly;
}
// 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;
}
/*
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection: (NSInteger)section
{
if (searchResults == nil) {
return 0;
} else if ([searchResults count] == 0) {
return 1;
} else {
return [self.objects count];
}
}
*/
// Override to customize the look of a cell representing an object. The default is to display
// a UITableViewCellStyleDefault style cell with the label being the first key in the object.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath: (NSIndexPath *)indexPath object:(PFObject *)object
{
static NSString *simpleTableIdentifier = #"RecipeCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier];
}
// Configure the cell
PFFile *thumbnail = [object objectForKey:#"imageFile"];
PFImageView *thumbnailImageView = (PFImageView*)[cell viewWithTag:100];
thumbnailImageView.image = [UIImage imageNamed:#"recipeBoxImage2.jpg"];
thumbnailImageView.file = thumbnail;
[thumbnailImageView loadInBackground];
UILabel *nameLabel = (UILabel*) [cell viewWithTag:101];
nameLabel.text = [object objectForKey:#"name"];
UILabel *prepTimeLabel = (UILabel*) [cell viewWithTag:102];
prepTimeLabel.text = [object objectForKey:#"prepTime"];
static NSString *LoadMoreCellIdentifier = #"LoadMoreCell";
UITableViewCell *loadcell = [self.tableView dequeueReusableCellWithIdentifier:LoadMoreCellIdentifier];
if (!cell) {
loadcell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:LoadMoreCellIdentifier];
}
return cell;
}
- (void)configureSearchResult:(SearchedResultCell *)cell atIndexPath: (NSIndexPath *)indexPath object:(PFObject *)object
{
static NSString *simpleTableIdentifier = #"RecipeCell";
SearchedResultCell *searchcell = [self.tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (searchcell == nil) {
searchcell = [[SearchedResultCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier];
}
// Configure the cell
PFFile *thumbnail = [object objectForKey:#"imageFile"];
PFImageView *thumbnailImageView = (PFImageView*)[cell viewWithTag:100];
thumbnailImageView.image = [UIImage imageNamed:#"recipeBoxImage2.jpg"];
thumbnailImageView.file = thumbnail;
[thumbnailImageView loadInBackground];
UILabel *nameLabel = (UILabel*) [cell viewWithTag:101];
nameLabel.text = [object objectForKey:#"name"];
UILabel *prepTimeLabel = (UILabel*) [cell viewWithTag:102];
prepTimeLabel.text = [object objectForKey:#"prepTime"];
}
// Set CellForRowAtIndexPath
- (UITableViewCell *)searchtableView:(UITableView *)searchtableView cellForRowAtIndexPath:(NSIndexPath *)indexPath object:(PFObject *)object
{
static NSString *CellIdentifier = #"SearchResultCell";
//Custom Cell
SearchedResultCell *cell = [searchtableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[SearchedResultCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
if ([searchResults count] == 0) {
//cell.mainTitle.text = #"Nothing Found";
return [self.tableView dequeueReusableCellWithIdentifier:NothingFoundCellIdentifier];
} else {
//#warning put your ClassName here
PFObject *object = [PFObject objectWithClassName:#"Recipe"];
object = [searchResults objectAtIndex:indexPath.row];
[self configureSearchResult:cell atIndexPath:indexPath object:object];
//[self configureSearchResult:cell atIndexPath:indexPath object:object];
return cell;
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForNextPageAtIndexPath:(NSIndexPath *)indexPath {
static NSString *LoadMoreCellIdentifier = #"LoadMoreCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:LoadMoreCellIdentifier];
if (!cell) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:LoadMoreCellIdentifier];
}
return cell;
}
//// Set TableView Height for Load Next Page
//- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath: (NSIndexPath *)indexPath {
// if([self.objects count] == indexPath.row) {
// // Load More Cell Height
// return 60.0;
// } else {
// return 80.0;
// }
//}
#pragma mark - UITableViewDelegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView deselectRowAtIndexPath:indexPath animated:YES];
[searchedBar resignFirstResponder];
if ([self.objects count] == indexPath.row) {
[self loadNextPage];
} else {
PFObject *photo = [self.objects objectAtIndex:indexPath.row];
NSLog(#"%#", photo);
// Do something you want after selected the cell
}
}
#pragma mark - UIScrollViewDelegate
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView {
[self.searchedBar resignFirstResponder];
}
//- (void)tableView:(UITableView *)tableView commitEditingStyle: (UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
//{
// // Remove the row from data model
// PFObject *object = [self.objects objectAtIndex:indexPath.row];
// [object deleteInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
// [self refreshTable:nil];
// }];
//}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:#"showRecipeDetail"]) {
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
RecipeDetailViewController *destViewController = segue.destinationViewController;
PFObject *object = [self.objects objectAtIndex:indexPath.row];
Recipe *recipe = [[Recipe alloc] init];
recipe.name = [object objectForKey:#"name"];
recipe.imageFile = [object objectForKey:#"imageFile"];
recipe.prepTime = [object objectForKey:#"prepTime"];
recipe.ingredients = [object objectForKey:#"ingredients"];
recipe.instructions = [object objectForKey:#"instructions"];
recipe.servings = [object objectForKey:#"servings"];
recipe.hotelSite = [object objectForKey:#"hotelSite"];
recipe.recipeType = [object objectForKey:#"recipeType"];
destViewController.recipe = recipe;
}
}
#end
found this - hope it helps others - credit to Bizzi-Body
https://github.com/Bizzi-Body/ParseTutorial-Part-2
//
// GourmetChefViewController.m
//
// Created by RedMac on 3/19/15.
//
#import "RecipeBookViewController.h"
#interface RecipeBookViewController ()
{
NSMutableArray *totalStrings;
NSMutableArray *filteredStrings;
BOOL isFiltered;
}
#end
#implementation RecipeBookViewController
#pragma mark -
#pragma mark UIViewController
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad
{
[super viewDidLoad];
self.mySearchBar.delegate =self;
self.myTableView.delegate = self;
self.myTableView.dataSource=self;
[self retrieveFromParse];
}
- (void) retrieveFromParse {
PFQuery *retrieveRecipes = [PFQuery queryWithClassName:#"Recipe"];
[retrieveRecipes whereKeyExists:#"name"];
[retrieveRecipes findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
if (!error) {
NSLog(#"%#", objects);
totalStrings = [[NSMutableArray alloc] initWithArray:objects];
}
[self.myTableView reloadData];
}];
}
-(NSInteger) numberOfSectionsInTableView:(UITableView *)tableView{
return 1;
}
-(void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *) searchText{
if (searchText.length ==0){
isFiltered =NO;}
else{
isFiltered =YES;
filteredStrings=[[NSMutableArray alloc]init];
for(PFObject *element in totalStrings) {
NSString * str = [element objectForKey:#"name"];
NSLog(#"%#", NSStringFromClass([element class])); // you thought that totalStrings
// contained NSString objects,
// but it contains PFObjects.
NSRange stringRange =[str rangeOfString:searchText options:NSCaseInsensitiveSearch];
if (stringRange.location !=NSNotFound) {
// you need to add the PFObject back to make your cellForRowAtIndexPath: method
// work.
[filteredStrings addObject:element]; // used to be :str
}
}
}
[self.myTableView reloadData];
}
//table view datasource and delegate method.....
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger) section
{
if (isFiltered){
return [filteredStrings count];
}return [totalStrings count];
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *CellIdentifier = #"RecipeCell";
UITableViewCell *cell= [tableView dequeueReusableCellWithIdentifier: CellIdentifier];
if (!cell){
cell=[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
if(!isFiltered){
PFObject *tempObject =[totalStrings objectAtIndex: indexPath.row];
cell.textLabel.text = [tempObject objectForKey:#"name"];
}
else
{
PFObject *tempObject2 =[filteredStrings objectAtIndex: indexPath.row];
cell.textLabel.text =[tempObject2 objectForKey:#"name"];
}
return cell;
}
- (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.
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
#end

multiple checkmarks from

Tutorial I am following: http://www.appcoda.com/ios-programming-tutorial-create-a-simple-table-view-app/
I have created a tableview with 16 cells. When I select a row, it will show checkmark on it.
But when I scroll the tableview, there is also a checkmark showing on another cell further down the list. This repeats for any cell selected.
#import "FlightChecklistViewController.h"
#interface FlightChecklistViewController ()
#end
#implementation FlightChecklistViewController
{
NSArray *tableData;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
// Initialize table data
tableData = [NSArray arrayWithObjects:#"Egg Benedict", #"Mushroom Risotto", #"Full Breakfast", #"Hamburger", #"Ham and Egg Sandwich", #"Creme Brelee", #"White Chocolate Donut", #"Starbucks Coffee", #"Vegetable Curry", #"Instant Noodle with Egg", #"Noodle with BBQ Pork", #"Japanese Noodle with Pork", #"Green Tea", #"Thai Shrimp Cake", #"Angry Birds Cake", #"Ham and Cheese Panini", nil];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [tableData count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *simpleTableIdentifier = #"SimpleTableItem";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier];
}
cell.textLabel.text = [tableData objectAtIndex:indexPath.row];
return cell;
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
UIAlertView *messageAlert = [[UIAlertView alloc]
initWithTitle:#"Row Selected" message:#"You've selected a row" delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
// Display Alert Message
[messageAlert show];
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
cell.accessoryType = UITableViewCellAccessoryCheckmark;
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}
#end
Any suggestions?
You need to store the information about the rows indexpaths, that were selected, somehow.
And populate your cell according to it.
#import "ViewController.h"
#interface ViewController ()
#property (nonatomic, strong) NSMutableArray *selectedCells;
#end
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
self.selectedCells = [NSMutableArray array];
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return 100;
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *unifiedID = #"aCellID";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:unifiedID];
if (!cell) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:unifiedID];
}
cell.textLabel.text = [NSString stringWithFormat:#"%u", indexPath.row];
//if the indexPath was found among the selected ones, set the checkmark on the cell
cell.accessoryType = ([self isRowSelectedOnTableView:tableView atIndexPath:indexPath]) ? UITableViewCellAccessoryCheckmark : UITableViewCellAccessoryNone;
return cell;
}
//if a row gets selected, toggle checkmark
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
if([self isRowSelectedOnTableView:tableView atIndexPath:indexPath]){
[self.selectedCells removeObject:indexPath];
cell.accessoryType = UITableViewCellAccessoryNone;
} else {
[self.selectedCells addObject:indexPath];
cell.accessoryType = UITableViewCellAccessoryCheckmark;
}
}
-(BOOL)isRowSelectedOnTableView:(UITableView *)tableView atIndexPath:(NSIndexPath *)indexPath
{
return ([self.selectedCells containsObject:indexPath]) ? YES : NO;
}
#end
you will find the complete example code on github
The problem is that cells are reused. So, if you add a checkmark accessory view to a cell further up it'll appear again when the cell is reused further down. You should save which ones are checkmarked in an array somewhere that correlates to the rows of the table when you add/remove a checkmark. Then, when you give the table view a new cell you can determine whether or not it needs a checkmark and set that up.
I had the same issue recently with one of my apps, and I fixed it by doing this:
#property (nonatomic, strong) NSArray *list;
- (void)viewDidLoad
{
[super viewDidLoad];
self.list = [[NSArray alloc] initWithObjects:#"foo", #"bar", nil];
}
- (NSString *)SettingsPlist
{
NSString *paths = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *PlistPath = [paths stringByAppendingPathComponent:#"Settings.plist"];
return PlistPath;
}
- (NSInteger)tableView:(UITableView *)tableView
numberOfRowsInSection:(NSInteger)section
{
return [[self list] count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *contentForThisRow = [[self list] objectAtIndex:[indexPath row]];
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"Cell"];
if(cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"Cell"];
}
NSDictionary *dict = [[NSDictionary alloc] initWithContentsOfFile:[self SettingsPlist]];
NSString *row = [NSString stringWithFormat:#"%d",indexPath.row];
if([[dict objectForKey:row]isEqualToString:#"0"])
{
cell.accessoryType = UITableViewCellAccessoryNone;
}
else
{
cell.accessoryType = UITableViewCellAccessoryCheckmark;
}
[[cell textLabel] setText:contentForThisRow];
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSMutableDictionary *plist = [NSMutableDictionary dictionaryWithContentsOfFile:[self SettingsPlist]];
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
NSString *row = [NSString stringWithFormat:#"%d",indexPath.row];
if(cell.accessoryType == UITableViewCellAccessoryNone)
{
cell.accessoryType = UITableViewCellAccessoryCheckmark;
NSString *on = #"1";
[plist setObject:on forKey:row];
[plist writeToFile:[self SettingsPlist] atomically:YES];
}
else if(cell.accessoryType == UITableViewCellAccessoryCheckmark)
{
cell.accessoryType = UITableViewCellAccessoryNone;
NSString *off = #"0";
[plist setObject:off forKey:row];
[plist writeToFile:[self SettingsPlist] atomically:YES];
}
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}

cannot delete the right cell in the table

I am making a small app. And having a trouble right now. Trouble by deleting a table customized cell.
it keep removing the top cell instead of the right selected cell. I delete cell number 20, it still delete the cell number 1. I don't know why. please help me out. Really appreciate.
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
[sortedArray removeObjectAtIndex:indexPath.row];
[self.tableView reloadData];
}
and here is the array:
- (void)viewDidLoad
{
[super viewDidLoad];
if (detail == nil) {
detail = [[UrlDetail alloc] init];
}
NSString *path = [[NSBundle mainBundle] pathForResource:#"data" ofType:#"plist"];
self.arrayData = [NSMutableArray arrayWithContentsOfFile:path];
NSMutableArray *filterArr = [self filterArray];
sortedArray = [[NSMutableArray alloc] initWithArray:filterArr copyItems:YES];
self.navigationItem.rightBarButtonItem = [[[UIBarButtonItem alloc]
initWithBarButtonSystemItem:UIBarButtonSystemItemAdd
target:self
action:#selector(actionAddNewURL:)] autorelease];
}
and here is the filter function:
-(NSMutableArray *)filterArray
{
NSMutableArray *filterArr = [[NSMutableArray alloc] init];
NSMutableArray *tempArray = [[NSMutableArray alloc] init];
[filterArr addObject:tempArray];
[tempArray release];
for (NSDictionary *item in arrayData) {
if ([tempArray count]==0)
{
[tempArray addObject:item];
}
else
{
NSDictionary *anItem = [tempArray objectAtIndex:0];
NSString *first = [[anItem objectForKey:#"url"] substringToIndex:1];
NSString *last = [[item objectForKey:#"url"] substringToIndex:1];
if ( [first isEqualToString:last])
{
[tempArray addObject:item];
} else
{
tempArray = [[NSMutableArray alloc] init];
[tempArray addObject:item];
[filterArr addObject:tempArray];
[tempArray release];
}
}
}
// NSMutableArray *newArray = [[NSMutableArray alloc] initWithArray:filterArr copyItems:YES];
return filterArr;
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
if([sortedArray count]>0){
NSLog(#"number of section: %d", [sortedArray count]);
return [sortedArray count];
}
return 0;
}
- (NSString *)tableView:(UITableView *)aTableView titleForHeaderInSection:(NSInteger)section
{
if (isTab) {
if ([self.sortedArray count] > section) {
NSDictionary *dictionary = [[sortedArray objectAtIndex:section] objectAtIndex:0];
NSString *string = [dictionary objectForKey:#"url"];
return [NSString stringWithFormat:#"%#", [[string substringToIndex:1] uppercaseString]];
}
else return nil;
} else
{
return nil;
}
}
- (UITableViewCell *)tableView:(UITableView *)aTableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
CustomCell *cell = (CustomCell *)[aTableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
[[NSBundle mainBundle] loadNibNamed:#"CustomCell" owner:self options:nil];
cell = myOwnCell;
}
NSDictionary *dataItem = [[sortedArray objectAtIndex:indexPath.section] objectAtIndex:indexPath.row];
cell.urlName.text = [dataItem objectForKey:#"url"];
cell.titleLabel.text = [dataItem objectForKey:#"title"];
cell.urlName.font = [UIFont italicSystemFontOfSize:14.0];
cell.imageIcon.image = [UIImage imageNamed:[dataItem objectForKey:#"image"]];
cell.accessoryType = UITableViewCellAccessoryDetailDisclosureButton;
cell.selectionStyle = UITableViewCellSelectionStyleNone;
// Configure the cell.
return cell;
}
Try this one if it works:
- (void) tableView:(UITableView *)aTableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath{
if (editingStyle == UITableViewCellEditingStyleDelete) {
NSString *key = [[sortedArray allKeys] objectAtIndex:indexPath.row];
[self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationTop];
[sortedArray removeObjectForKey:key];
}
}