I have implemented the search functionality as below. I am able to retrieve the rows based on search string but they are empty, when i click on the empty search result cell am able to navigate correctly for each search result.I am using story board configured cells to display the table. I mean am using tags in order to populate the data and the images.
- (void)viewDidLoad
{
sqlDatabase = [SQLiteDatabase getDatabaseInstance];
filteredItemist=[[NSMutableArray alloc] initWithArray:[sqlDatabase fetchCropListBySoilName:soilName]];
[super viewDidLoad];
}
- (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] ;
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
}
// Configure the cell...
Crop * crop = [filteredItemist objectAtIndex:[indexPath row]];
NSString* str = [NSString stringWithFormat:#"%#.jpg",crop.cropName.lowercaseString];
UIImageView *cropImageView = (UIImageView *)[cell viewWithTag:100];
cropImageView.image = [UIImage imageNamed:str];
UILabel *cropNameLabel = (UILabel *)[cell viewWithTag:70];
cropNameLabel.text = [crop cropName];
return cell;
}
- (void)viewWillAppear:(BOOL)animated
{
self.navigationItem.title = #"Item List";
filteredItemist = [[NSMutableArray alloc]initWithArray:[sqlDatabase fetchCropListBySoilName:soilName]];
[self.tableView reloadData];
self.navigationController.toolbarHidden = YES;
[super viewWillAppear:animated];
}
- (void)filterContentForSearchText:(NSString*)searchText
{
if([searchText length] == 0)
{
isFiltered = FALSE;
[filteredItemist removeAllObjects];
[filteredItemist addObjectsFromArray:[sqlDatabase fetchCropListBySoilName:soilName]];
}
else{
isFiltered = TRUE;
[filteredItemist removeAllObjects];
for(Crop *i in [sqlDatabase fetchCropListBySoilName:soilName]){
NSRange stringRange = [[i cropName]rangeOfString:searchText options:NSCaseInsensitiveSearch];
if(stringRange.location !=NSNotFound){
[filteredItemist addObject:i];
}
}
}
[self.tableView reloadData];
}
- (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString
{
[self filterContentForSearchText:searchString];
return YES;
}
-(void)searchBarSearchButtonClicked:(UISearchBar *)searchBar
{
[self.searchBar resignFirstResponder];
}
Edit :
after changing the code to self.tableview :
Instead of this :
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
use this :
UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:CellIdentifier];
Search results displayed in a separate table view. So if you use tableView without self you may be referring search results table view.
Related
I have made one sample demo.
Like selected cell print after "Done"button clicked.
It is working fine.
Code is
#synthesize arrayContainer,filteredRecipes,myTableView,filtered,selectedRaw;
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.arrayContainer = [[NSMutableArray alloc]initWithObjects:#"One",#"Two",#"Three",#"Four",#"Five",#"Six",#"Seven",#"Eight",#"Nine", nil];
self.selectedRaw = [[NSMutableArray alloc]init];
}
-(IBAction)printSelectedItem:(id)sender
{
NSLog(#"The Selected Items are %#",self.selectedRaw);
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if(filtered == YES)
{
return self.filteredRecipes.count;
}
else
{
return self.arrayContainer.count;
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *identifier = #"myCell";
UITableViewCell *cell =[tableView dequeueReusableCellWithIdentifier:identifier];
if(filtered == YES)
{
cell.textLabel.text = [self.filteredRecipes objectAtIndex:indexPath.row];
}
else
{
cell.textLabel.text = [self.arrayContainer objectAtIndex:indexPath.row];
}
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(nonnull NSIndexPath *)indexPath{
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
if (cell.accessoryType == UITableViewCellAccessoryCheckmark) {
cell.accessoryType = UITableViewCellAccessoryNone;
// NSString *string = [self.selectedRaw objectAtIndex:indexPath.row];
[self.selectedRaw removeObjectAtIndex:indexPath.row];
} else {
cell.accessoryType = UITableViewCellAccessoryCheckmark;
NSString *temp = [self.arrayContainer objectAtIndex:indexPath.row];
[self.selectedRaw addObject:temp];
}
}
- (void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar
{
[searchBar setShowsCancelButton:YES animated:YES];
}
-(void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText
{
if([searchText length] == 0)
{
self.filtered = NO;
}
else
{
self.filtered = YES;
self.filteredRecipes = [[NSArray alloc]init];
NSPredicate *resultPredicate = [NSPredicate predicateWithFormat:#"SELF contains[cd] %#",searchText];
filteredRecipes = [self.arrayContainer filteredArrayUsingPredicate:resultPredicate];
}
[self.myTableView reloadData];
}
Question is
-> When I print selected row of table view ,Displayed in log perfectly.
-> But when I deselected those selected item it gives me n error.
Please give me solution.
My another question is when I have searched particular item (selected) it gives me selected item perfectly,then i deselect item after I have canceled searching then it gives me again selected item which I did deselect earlier.
Output image
selected Raw
Unchecked second raw
So please try this.
#import "SecondViewController.h"
#interface SecondViewController ()
#property(nonatomic,strong)NSArray *arrayContainer;
#property(nonatomic,strong)NSArray *filteredRecipes;
#property(nonatomic,strong)NSMutableArray *selectedRaw;
#property(nonatomic,assign)BOOL filtered;
#end
#implementation SecondViewController
- (void)viewDidLoad {
[super viewDidLoad];
_arrayContainer = #[#"One",#"Two",#"Three",#"Four"];
// _arrayContainer = [[NSMutableArray alloc]initWithArray:];
_selectedRaw = [[NSMutableArray alloc]init];
[self.tableView reloadData];
// Do any additional setup after loading the view.
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
/*
#pragma mark - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
// Get the new view controller using [segue destinationViewController].
// Pass the selected object to the new view controller.
}
*/
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
return 1;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
if(_filtered)
return _filteredRecipes.count;
else
return _arrayContainer.count;
}
-(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"Cell" forIndexPath:indexPath];
if(_filtered){
NSString *tmp = [_filteredRecipes objectAtIndex:indexPath.row];
cell.textLabel.text = tmp;
if([_selectedRaw containsObject:tmp])
cell.accessoryType = UITableViewCellAccessoryCheckmark;
else
cell.accessoryType = UITableViewCellAccessoryNone;
}else{
NSString *tmp = [_arrayContainer objectAtIndex:indexPath.row];
cell.textLabel.text = tmp;
if([_selectedRaw containsObject:tmp])
cell.accessoryType = UITableViewCellAccessoryCheckmark;
else
cell.accessoryType = UITableViewCellAccessoryNone;
}
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(nonnull NSIndexPath *)indexPath{
if(self.filtered){
if([self.selectedRaw containsObject:[self.filteredRecipes objectAtIndex:indexPath.row]]){
[self.selectedRaw removeObjectAtIndex:[self.selectedRaw indexOfObject:[self.filteredRecipes objectAtIndex:indexPath.row]]];
}else{
NSString *temp = [self.filteredRecipes objectAtIndex:indexPath.row];
[self.selectedRaw addObject:temp];
}
}else{
if([self.selectedRaw containsObject:[self.arrayContainer objectAtIndex:indexPath.row]]){
[self.selectedRaw removeObjectAtIndex:[self.selectedRaw indexOfObject:[self.arrayContainer objectAtIndex:indexPath.row]]];
}else{
NSString *temp = [self.arrayContainer objectAtIndex:indexPath.row];
[self.selectedRaw addObject:temp];
}
}
[self.tableView reloadData];
}
-(void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText{
if([searchText length] == 0)
{
self.filtered = NO;
}
else
{
self.filtered = YES;
NSPredicate *resultPredicate = [NSPredicate predicateWithFormat:#"SELF contains[cd] %#",searchText];
_filteredRecipes = [self.arrayContainer filteredArrayUsingPredicate:resultPredicate];
}
[self.tableView reloadData];
}
-(void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar{
_filtered = !_filtered;
}
-(void)searchBarTextDidEndEditing:(UISearchBar *)searchBar{
_filtered = !_filtered;
}
#end
You have to remove data based on Object not based on Index so here you can go with below code:
1st you have to check filter condition in your didselect method
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(nonnull NSIndexPath *)indexPath{
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
if(filtered == YES)
{
if (cell.accessoryType == UITableViewCellAccessoryCheckmark) {
cell.accessoryType = UITableViewCellAccessoryNone;
[self.selectedRaw removeObject:[self.filteredRecipes objectAtIndex:indexPath.row]];
} else {
cell.accessoryType = UITableViewCellAccessoryCheckmark;
[self.selectedRaw addObject:[self.filteredRecipes objectAtIndex:indexPath.row]]
}
}
else
{
if (cell.accessoryType == UITableViewCellAccessoryCheckmark) {
cell.accessoryType = UITableViewCellAccessoryNone;
[self.selectedRaw removeObject:[self.arrayContainer objectAtIndex:indexPath.row]];
} else {
cell.accessoryType = UITableViewCellAccessoryCheckmark;
[self.selectedRaw addObject:[self.arrayContainer objectAtIndex:indexPath.row]]
}
}
}
2nd Problem solution:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *identifier = #"myCell";
UITableViewCell *cell =[tableView dequeueReusableCellWithIdentifier:identifier];
if(filtered == YES)
{
cell.textLabel.text = [self.filteredRecipes objectAtIndex:indexPath.row];
if([selectedRaw containsObject:self.filteredRecipes[indexPath.row]] ){
cell.accessoryType = UITableViewCellAccessoryCheckmark;
}else{
cell.accessoryType = UITableViewCellAccessoryNone;
}
}
else
{
cell.textLabel.text = [self.arrayContainer objectAtIndex:indexPath.row];
if([selectedRaw containsObject:self.arrayContainer[indexPath.row]] ){
cell.accessoryType = UITableViewCellAccessoryCheckmark;
}else{
cell.accessoryType = UITableViewCellAccessoryNone;
}
}
return cell;
}
Hope This will helps you.
1: You have to take array with dictionary with parameter like
[{
value : “One”,
state : “Check”
},
{
value : “Two”,
state : “UnCheck”
}
]
then on cellForRowAtindexParth
if (self.selectedRaw[indexPath.row] as ! NSDictionary).value(forKey:”state”) as! String == “Check”{
//change to check mark
}
else{
//change to UnCheck mark
}
At DidSelectRowAtIndexPath
if (cell.accessoryType == UITableViewCellAccessoryCheckmark) {
if (arr[indexPath.row] as ! NSDictionary).value(forKey:”state”) as! String == “Check”{
//change state value to UnCheck
}else{
//change state value to Check
}
}
2:On second point you need to do same work
Im working on a tableview with a searchBardisplayController but when I type a search this shows the correct results but when I select the cell shows me a different selection (such as if I select a cell when the tableview is normal, the normal indexpath)
So heres my code:
number of rows
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// NSLog(#"%i", [[InfoWebDoctores sharedInstance]numberOfInfo]);
if (tableView == self.searchDisplayController.searchResultsTableView) {
return [displayObject count];
} else {
return [allObject count];
}
}
Configure the cell:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"docCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if(!cell)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:#"docCell"];
}
return cell;
}
Make the search:
- (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString
{
if([searchString length] == 0)
{
[displayObject removeAllObjects];
[displayObject addObjectsFromArray:allObject];
}
else
{
[displayObject removeAllObjects];
for(NSDictionary *tmpDict in allObject)
{
NSString *val = [tmpDict objectForKey:doctorname];
NSRange r = [val rangeOfString:searchString options:NSCaseInsensitiveSearch];
NSString *val2 = [tmpDict objectForKey:doctoresp];
NSRange r2 = [val2 rangeOfString:searchString options:NSCaseInsensitiveSearch];
if(r2.location != NSNotFound || r.location != NSNotFound)
{
[displayObject addObject:tmpDict];
}
}
}
return YES;
}
And finally sending the data to the detailViewcontroller (Ive tryied with push connection but when I select a searchresult Cell not even get the push view...)
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
DetailTableViewController *detail = [self.storyboard instantiateViewControllerWithIdentifier:#"detailController"];
NSIndexPath *index = [self.searchDisplayController.searchResultsTableView indexPathForSelectedRow];
//NSIndexPath *index = [self.tableView indexPathForSelectedRow];
int row = [index row];
EntryJsonDoctores *entry = [[InfoWebDoctores sharedInstance]entryAtIndex:row];
detail.modal = #[entry.nombre,entry.especialidad, entry.especialidad2, entry.especialidad3, entry.cel, entry.mail, entry.tel1, entry.tel2, entry.ext,entry.hospital,entry.direccion];
[self presentViewController:detail animated:YES completion:^{
}];
}
So Ive tryied with the indexpathforselectedrow from the tableview and the indexpath from searchresultscontroller, whats wrong? I need someones help please
If you set the search display controller's resultsTableView's delegate to this View Controller, then the results TableView will be looking for the didSelectRowAtIndexPath.
You can do this in the viewDidLoad and put self.searchDisplayController.searchResultsTableView.delegate = self
Replace NSIndexPath *index = [self.searchDisplayController.searchResultsTableView indexPathForSelectedRow]; with NSIndexPath *index = indexPath;
I created an RSS reader that parses from a .xml file. I am trying to create a search bar and search display controller, but am not sure how to search the objectForKey "title" or objectForKey "summary" within the UITableView.
Any help would be greatly appreciated.
The numberOfRowsInSection and cellForRowAtIndexPath looked like this:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
return self.parseResults.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
//Check if cell is nil. If it is create a new instance of it
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
}
// Configure titleLabel
cell.textLabel.text = [[self.parseResults objectAtIndex:indexPath.row] objectForKey:#"title"];
cell.textLabel.numberOfLines = 2;
//Configure detailTitleLabel
cell.detailTextLabel.text = [[self.parseResults objectAtIndex:indexPath.row] objectForKey:#"summary"];
cell.detailTextLabel.numberOfLines = 2;
//Set accessoryType
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
//Set font and style
cell.selectionStyle = UITableViewCellSelectionStyleGray;
cell.textLabel.font = [UIFont boldSystemFontOfSize:14];
return cell;
}
I recently tried to follow this sample project - https://github.com/deepthit/TableViewSearch.git - based on a suggestion.
My code then looked like this:
#interface QldRecentJudgmentsViewController () {
__strong NSArray *mFilteredArray_;
__strong UISearchBar *mSearchBar_;
__strong UISearchDisplayController *mSearchDisplayController_;
}
#end
#implementation ViewController
#synthesize parseResults = _parseResults, HUD;
- (void)viewDidLoad {
[super viewDidLoad];
mSearchBar_ = [[UISearchBar alloc] initWithFrame:CGRectMake(0,
0,
self.view.bounds.size.width,
44)];
mSearchBar_.delegate = self;
mSearchBar_.placeholder = #"search";
self.tableView.tableHeaderView = mSearchBar_;
mSearchDisplayController_ = [[UISearchDisplayController alloc] initWithSearchBar:mSearchBar_
contentsController:self];
mSearchDisplayController_.searchResultsDelegate = self;
mSearchDisplayController_.searchResultsDataSource = self;
mSearchDisplayController_.delegate = self;
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
// Return the number of rows in the section.
//return self.parseResults.count;
if (tableView == self.searchDisplayController.searchResultsTableView ||
[mFilteredArray_ count] > 0)
{
return [mFilteredArray_ count];
}
return parseResults.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
id result;
if (tableView == self.searchDisplayController.searchResultsTableView ||
[mFilteredArray_ count] > 0)
{
result = [mFilteredArray_ objectAtIndex:indexPath.row];
}
else
{
result = [parseResults objectAtIndex:indexPath.row];
}
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
//Check if cell is nil. If it is create a new instance of it
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
}
// Configure titleLabel
cell.textLabel.text = [[self.parseResults objectAtIndex:indexPath.row] objectForKey:#"title"];
cell.textLabel.numberOfLines = 2;
//Configure detailTitleLabel
cell.detailTextLabel.text = [[self.parseResults objectAtIndex:indexPath.row] objectForKey:#"summary"];
cell.detailTextLabel.numberOfLines = 2;
//Set accessoryType
//cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
//Set font and style
cell.selectionStyle = UITableViewCellSelectionStyleGray;
cell.textLabel.font = [UIFont boldSystemFontOfSize:14];
return cell;
}
#pragma mark - Table view delegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSString *url = [[self.parseResults objectAtIndex:indexPath.row] objectForKey:#"link"];
NSString *title = [[self.parseResults objectAtIndex:indexPath.row] objectForKey:#"title"];
WebViewController *viewController = [[WebViewController alloc] initWithURL:url title:title];
[self.navigationController pushViewController:viewController animated:YES];
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}
#pragma mark - UISearchBarDelegate
- (void)searchBar:(UISearchBar *)searchBar
textDidChange:(NSString *)searchText {
if ([searchText length] == 0)
{
[self.tableView reloadData];
return;
}
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"SELF.title contains[cd] %# OR SELF.summary contains[cd] %#", searchText, searchText];
mFilteredArray_ = [self.parseResults filteredArrayUsingPredicate:predicate];
[self.tableView reloadData];
}
- (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar
{
mFilteredArray_ = nil;
[self.tableView reloadData];
}
However, when I follow this the RSS feed does not load anymore in the tableview, so there are no results. Nevertheless when I try to search it does not correctly search the "title" or "summary" and the search results do not appear correctly -the cells are not neatly aligned after searching for something and getting results. Also, the only way to see RSS in the tableview is to search for any generic string, but once you press cancel in the search bar the RSS feed disappears and shows an empty tableview.
Thanks for any help in advance.
Edited code
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell==nil)
cell=[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
if (isFiltered) {
int rowCount=indexPath.row;
Aves *filtrada=[filteredTableData objectAtIndex:rowCount];
cell.textLabel.text=filtrada.name;
NSLog(#"mostrando: ");
}else {
int rowCounter=indexPath.row;
Aves *author=[theauthors objectAtIndex:rowCounter];
cell.textLabel.text=author.name;
}
NSLog(#"mostrando: ");
return cell;
}
-(void)searchBar:(UISearchBar*)searchBar textDidChange:(NSString*)text
{
if(text.length == 0)
{
isFiltered = FALSE;
}
else
{
isFiltered = true;
int i;
[filteredTableData removeAllObjects];
for(i=0;[theauthors count]>i;i++)
{
Aves *name=[theauthors objectAtIndex:i];
//NSLog(name.name);
NSRange nameRange = [[name.name lowercaseString] rangeOfString:[text lowercaseString]];
if(nameRange.length>0)
{
[filteredTableData addObject:name];
NSLog(name.name);
}
}
[self.tableView performSelectorOnMainThread:#selector(reloadData) withObject:nil waitUntilDone:NO];
}
}
Edit: After working on it a while I solved some problems.Just updated my code, the problem is the repaint of the tableView, every thing else go ok. Check it and give any ideas you have plz ^^
Thx again for your time.
I assume you're using prototype cells? I just had a similar problem in one of my projects.
When search results are displayed and tableView:cellForRowAtIndexPath: is called, the table view passed in the the table belonging to the search results controller, not your main table view. Problem with that is, the search results table view doesn't know anything about your table's prototype cells, so dequeueReusableCellWithIdentifier: returns nil. But just alloc/init'ing a UITableCellView won't give you one of your prototype cells, so whatever UI you laid out in your storyboard isn't there.
The fix is easy: in tableView:cellForRowAtIndexPath:, don't call dequeueReusableCellWithIdentifier: on the tableview passed in; just call it on your main table view. So basically, just change this:
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell==nil)
cell=[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
to this:
UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:CellIdentifier];
There's no need for the nil check; Apple's Storyboards Release Notes says:
The dequeueReusableCellWithIdentifier: method is guaranteed to return
a cell (provided that you have defined a cell with the given
identifier). Thus there is no need to use the “check the return value
of the method” pattern as was the case in the previous typical
implementation of tableView:cellForRowAtIndexPath:.
does your app hits this code if(nameRange.location ==0) ?
Change the code piece of
else
{
isFiltered = true;
int i=0;
[filteredTableData removeAllObjects];
filteredTableData = [[NSMutableArray alloc] init];
//for (Aves* name in theauthors)
for(i=0;[theauthors count]>i;i++)
{
Aves *name=[theauthors objectAtIndex:i];
NSRange nameRange = [name.foodName rangeOfString:text ];
if(nameRange.location ==0)
{
[filteredTableData addObject:name];
}
[self.tableView reloadData];
}
}
to
else
{
isFiltered = true;
int i=0;
[filteredTableData removeAllObjects];
//filteredTableData = [[NSMutableArray alloc] init]; not needed
//for (Aves* name in theauthors)
for(i=0;[theauthors count]>i;i++)
{
Aves *name=[theauthors objectAtIndex:i];
NSRange nameRange = [name.foodName rangeOfString:text ];
if(nameRange.location != NSNotFound)
{
[filteredTableData addObject:name];
}
}
[self.tableView reloadData];
}
use this:
- (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 (isFiltered)
{
return [filteredTableData count];
}
else
{
return [theauthors count];
}
}
Replace method:
-(void)searchBar:(UISearchBar*)searchBar textDidChange:(NSString*)text
{
if(text.length == 0)
{
isFiltered = FALSE;
}
else
{
isFiltered = true;
int i=0;
[filteredTableData removeAllObjects];
filteredTableData = [[NSMutableArray alloc] init];
//for (Aves* name in theauthors)
for(i=0;[theauthors count]>i;i++)
{
Aves *name=[theauthors objectAtIndex:i];
NSRange nameRange = [[name.foodName lowercaseString] rangeOfString:[text lowercaseString]];
if(nameRange.length>0)
{
[filteredTableData addObject:name];
[self.tableView reloadData];
}
}
}
}
finally fixed it. Here is my working code, thx you all =)
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:CellIdentifier];
cell=[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:CellIdentifier];
if (isFiltered==TRUE) {
int rowCount=indexPath.row;
//for (rowCount=0; rowCount<[filteredTableData count]; rowCount++) {
Aves *filtrada=[filteredTableData objectAtIndex:rowCount];
cell.textLabel.text=filtrada.name;
//}
}else if(isFiltered==FALSE)
{
int rowCounter=indexPath.row;
Aves *author=[theauthors objectAtIndex:rowCounter];
cell.textLabel.text=author.name;
}
return cell;
}
-(void)searchBar:(UISearchBar*)searchBar textDidChange:(NSString*)text {
[filteredTableData removeAllObjects];
filteredTableData=[[NSMutableArray alloc]init ];
if(text.length == 0)
{
isFiltered = FALSE;
}
else
{
isFiltered = TRUE;
int i;
for(i=0;[theauthors count]>i;i++)
{
Aves * filtrado=[[Aves alloc]init];
filtrado=[theauthors objectAtIndex:i];
//NSLog(filtrado.name);
NSRange nameRange = [[filtrado.name lowercaseString] rangeOfString:[text lowercaseString]];
if(nameRange.length>0)
{
[filteredTableData addObject:filtrado];
}
}
[self.tableView performSelectorOnMainThread:#selector(reloadData) withObject:nil
waitUntilDone:NO];
}
}
You probably want to replace
UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:CellIdentifier];
cell=[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:CellIdentifier];
with in your cellForRowAtIndexPath
UITableViewCell *cell=[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:CellIdentifier];
The reason because you're not getting use of the dequeued cell anyway.
I have a delegate, but it doesn't work without the other delegate line in it:
- (id)initWithData:(NSData *)data delegate:(id <ParseOperationDelegate>)theDelegate {
self = [super init];
if (self != nil) {
self.dataToParse = data;
self.delegate = theDelegate;
}
appDelegate = (XMLAppDelegate *)[[UIApplication sharedApplication] delegate];
return self;
}
It should load data in a Cell but the data isn't shown before the first scroll. What can I do?
EDIT:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"productCell";
static NSString *PlaceholderCellIdentifier = #"placeholderCell";
int nodeCount = [appDelegate.products count];
if (nodeCount == 0 && indexPath.row == 0) {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:PlaceholderCellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:PlaceholderCellIdentifier];
cell.detailTextLabel.textAlignment = UITextAlignmentCenter;
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
}
cell.detailTextLabel.text = #"Loading...";
return cell;
}
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
}
if (nodeCount > 0) {
XMLProductView *listedProduct = [appDelegate.products objectAtIndex:indexPath.row];
cell.textLabel.text = listedProduct.name;
// cell.detailTextLabel.text = appRecord.artist;
if (!listedProduct.productImage) {
if (self.tableView.dragging == NO && self.tableView.decelerating == NO) {
[self startImageDownload:listedProduct forIndexPath:indexPath];
}
UIImageView *listedImage = (UIImageView *)[cell viewWithTag:1];
listedImage.image = [UIImage imageNamed:#"Placeholder.png"];
}
else {
UIImageView *listedImage = (UIImageView *)[cell viewWithTag:1];
listedImage.image = listedProduct.productImage;
}
}
return cell;
}
your code seems that its waiting for some event, or some files to get fetched or downloaded, so you will need to call [tableview reloadData]; when this data is downloaded,
I cant figure it out from the code, but my guts tells me this
1st:
that you are waiting for data from int nodeCount = [appDelegate.products count]; to be ready, so you will need to have some sort of delegate that gets called when this data is ready
2nd:
you are waiting for an image to get downloaded here [self startImageDownload:listedProduct forIndexPath:indexPath], so when this actually get downloaded you will need to set the image to that cell or reloadData on the table
That is what i can figure out from the code.