How to load tableview based on button values with custom cells? - objective-c

In my app I want to display a tableview(custom cells) based on button tags,when I am clicking on my 1st button it is showing empty table view and clicking on 2nd button it is showing 1st button data.
Here is my Code upto now i tried,
I am Calling my IBAction button in ViewDidLoad Method,
- (void)viewDidLoad
{
value1=0;
[self details:nil];
}
Here is my IBAction Method,
-(IBAction)details:(id)sender
{
value1 = 0;
detaiLine.hidden = NO;
rewardLine.hidden = YES;
[testTableView reloadData];
}
Here is my tableViewDataSource Methods,
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return responseArray.count;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
if (value1 == 0)
{
return 104;
}
if(value1 == 1)
{
return 180;
}
return 0;
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
if (value1 == 0)
{
static NSString *cellId = #"Cell1";
ContestDetailCell1 * cell = (ContestDetailCell1 *)[contestTableView dequeueReusableCellWithIdentifier:cellId];
if (cell == nil)
{
NSArray *myNib;
myNib = [[NSBundle mainBundle]loadNibNamed:#"ContestDetailCell1" owner:self options:nil];
cell = [myNib lastObject];
}
}
if(value1 == 1)
{
static NSString *cellIdentifier = #"Cell2";
ContestDetailCell2 *cell = (ContestDetailCell2 *)[contestTableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell == nil)
{
NSArray *myNib;
myNib = [[NSBundle mainBundle]loadNibNamed:#"ContestDetailCell2" owner:self options:nil];
cell =[myNib objectAtIndex:0];
}
}
What is the problem in my code.

You are not assigning tag value to your value1 variable. Try this code,
-(IBAction)details:(id)sender
{
value1 = sender.tag;
detaiLine.hidden = NO;
rewardLine.hidden = YES;
[testTableView reloadData];
}

I think that you have not implemented your logic correctly. I didn't understand why you are calling IBAction from viewdidload.
Please find this as a work around,
add tag for each button in xib or using code.
In your IBAction Method get the tag and identify the button as follows,
-(IBAction)details:(id)sender
{
value1 = sender.tag;
\\your remaining code here
}
Using this value1 load your data in table view.
Hope this will help you. Please correct me if i'm wrong. :P

Related

UITableView scroll is never end after search

I have UITableView to show whole bunch of words from array.
I also provide search bar on top of table view so when people type a word in textbox search then my code start filtering data from array.
My result is good but my scroll in tableview is never end even though there is only one row.
My tableview result can scroll down and down without no row.
I don't know what going on with my table view.
My code that I have implement.
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
if(self.tableView == tableView){
return [self.alphabet count];
}else{
return 1;
}
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if (self.tableView == tableView) {
return [[self.vocabularyInfo objectAtIndex:section] count];
}else{
return [self.filteredVocabs count];
}
}
-(NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
return [self.alphabet objectAtIndex:section];
}
- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView
{
if(self.tableView == tableView){
return self.alphabet;
}else{
return nil;
}
}
// Display cell
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *cellIdentifier = #"CommentTableCell";
//-- try to get a reusable cell --
CommentTableCell *cell = (CommentTableCell *) [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
//-- create new cell if no reusable cell is available --
if (cell == nil)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:cellIdentifier owner:self options:nil];
cell = [nib objectAtIndex:0];
}
VocabularyController *vc;
// Display word from database else display vocabulary when searching
if (tableView != self.searchDisplayController.searchResultsTableView) {
vc = [self.vocabularyInfo[indexPath.section] objectAtIndex:indexPath.row];
}else{
vc = [self.filteredVocabs objectAtIndex:indexPath.row];
}
cell.nameLabel.text = vc.korean;
return cell;
}
// My method that I used for filtering my array to display the result
- (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString{
if (searchString.length > 0) {
NSArray *vocabToSearch = self.vocabularyInfo;
if (self.currentSearchString.length > 0 && [searchString rangeOfString:self.currentSearchString].location == 0) {
vocabToSearch = self.filteredVocabs;
}
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"korean CONTAINS[cd] %#", searchString];
self.filteredVocabs = [vocabToSearch filteredArrayUsingPredicate:predicate];
} else {
self.filteredVocabs = self.vocabularyInfo;
}
self.currentSearchString = searchString;
return YES;
}
Please help me!!
Check your tableview's datasource delegate function.
Maybe more detail about your implementation is helpful.
Please check the value you are returning for the number of rows in the following method:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section

iOS custom cell expandable - index 0 issue

Thanks for the help.
I have a custom cell that I expand using the following code. However, the first cell (index 0) always expands upon launch of the ViewControllers?
What am I missing? How do you have them all unExpanded upon launch and expand only upon selection.
Many Thanks.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
CustomCellCell *cell;
static NSString *cellID=#"myCustomCell";
cell = [tableView dequeueReusableCellWithIdentifier:cellID];
if (cell == nil)
{
NSArray *test = [[NSBundle mainBundle]loadNibNamed:#"myCustomCell" owner:nil options:nil];
if([test count]>0)
{
for(id someObject in test)
{
if ([someObject isKindOfClass:[CustomCellCell class]]) {
cell=someObject;
break;
}
}
}
}
cell.LableCell.text = [testArray objectAtIndex:[indexPath row]];
NSLog( #"data testarray table %#", [testArray objectAtIndex:[indexPath row]]);
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
return cell;
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
self.selectedRow = indexPath.row;
CustomCellCell *cell = (CustomCellCell *)[tableView cellForRowAtIndexPath:indexPath];
[tableView beginUpdates];
[tableView endUpdates];
cell.buttonCell.hidden = NO;
cell.textLabel.hidden = NO;
cell.textfiledCell.hidden = NO;
cell.autoresizingMask = UIViewAutoresizingFlexibleHeight;
cell.clipsToBounds = YES;
cell.accessoryType = UITableViewCellAccessoryNone;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
if(selectedRow == indexPath.row) {
return 175;
}
return 44;
}
That is because default value of selectedRow is zero. You need to initialize it as,
selectedRow = NSIntegerMax; //or selectedRow = -1;
or some other default value. You can add this in viewDidLoad method or so. Whenever you declare an int type variable, it is default value is zero. So if you have a scenario where zero needs to be checked for example in the above case, you should default it to a value which wont be used at all. Either a negative value or NSIntegerMax can be used for this.
I'm guessing that selectedRow is an integer instance variable. That integer begins life with a value of 0. As the first table cell is row 0, it matches selectedRow even though you have not intentionally set it.
One way to solve this would be to store selectedRow as an NSIndexPath instead of an integer.
Then you could just do this:
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
if([selectedRow isEqual:indexPath]) {
return 175;
}
return 44;
}
And because selectedRow will default to nil, you won't get a false match. It is also more flexible if you decide to use sections later on.

UISearchDisplayController Not Displaying Results in searchResultsTableView

I have a UISearchDisplayController properly connected to the header of a custom UITableView in IB. However, when I search for anything the searchResultsTableView only displays "No Results", and I cannot seem to find where the code is incorrect.
searchResults Property
- (NSMutableArray *)searchResults {
if (!_searchResults) {
_searchResults = [[NSMutableArray alloc] initWithCapacity:self.listingPreviews.count];
}
return _searchResults;
}
Table View Data Source Methods
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
// Return the number of rows in the section.
NSInteger numberOfRows = 0;
if (tableView == self.tableView) {
numberOfRows = self.listingPreviews.count;
} else {
numberOfRows = self.searchResults.count;
}
return numberOfRows;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Listing";
ListingPreviewTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (!cell) {
cell = [[ListingPreviewTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
// Configure the cell.
if (tableView == self.tableView) {
cell.listingPreview = [self.listingPreviews objectAtIndex:indexPath.row];
} else {
NSLog([[self.searchResults objectAtIndex:indexPath.row] title]);
cell.listingPreview = [self.searchResults objectAtIndex:indexPath.row];
}
return cell;
}
Search Bar Delegate Method
- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText {
NSInteger searchTextLength = searchText.length;
for (ListingPreview *listingPreview in self.listingPreviews) {
if ((listingPreview.title.length >= searchTextLength) && ([listingPreview.title rangeOfString:searchText].location != NSNotFound)) {
[self.searchResults addObject:listingPreview];
}
}
}
Just try this instead:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Listing";
ListingPreviewTableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:CellIdentifier];
// Configure the cell.
if (tableView == self.tableView) {
cell.listingPreview = [self.listingPreviews objectAtIndex:indexPath.row];
} else {
NSLog([[self.searchResults objectAtIndex:indexPath.row] title]);
cell.listingPreview = [self.searchResults objectAtIndex:indexPath.row];
}
return cell;
}
Please note that the change was applied on:
ListingPreviewTableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:CellIdentifier];
This way you deque a Cell from your own tableView and not from the one created by UISearchDisplayController.
It seems that nothing in your code forces searchDisplayController to reload it's searchResultTableView.
The standard approach is to set UISearcDisplayController's delegate (note the protocol - UISearchDisplayDelegate) and implement – searchDisplayController:shouldReloadTableForSearchString:
- (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString {
// perform your search here and update self.searchResults
NSInteger searchStringLength = searchString.length;
for (ListingPreview *listingPreview in self.listingPreviews) {
if ((listingPreview.title.length >= searchStringLength) && ([listingPreview.title rangeOfString:searchString].location != NSNotFound)) {
[self.searchResults addObject:listingPreview];
}
}
// returning YES will force searchResultController to reload search results table view
return YES;
}

Display multiple custom cells in a UITableView?

I am using Xcode 4.2 on SnowLeopard, and my project is using storyboards. I am trying to implement a UITableView with 2 different custom cell types, sessionCelland infoCell. I can get the 2 types to appear within the same list, but now I have a new problem?! The sessionCell is displayed once, and then X number of infoCells are displayed after it - just as I wanted - except that the first infoCell is always overwritten by the sessionCell!
- (NSInteger)tableView:(UITableView *)tableView
numberOfRowsInSection:(NSInteger)section
{
return [self.people count];
}
//inside cellForRowAtIndexPath
if(indexPath.row == 0) {
cell = [tableView dequeueReusableCellWithIdentifier:#"sessionCell"];
} else {
cell = [tableView dequeueReusableCellWithIdentifier:#"infoCell"];
}
...
return cell;
I've tried to say return array count + 1, or even hardcoded return 7 (it fits my example) but both are incorrect!
myObject *person = [self.people objectAtIndex:indexPath.row];
Or does my problem lie in the above line? I've even tried indexPath.row+1...
Any help would be greatly appreciated!!
If I understand your question correctly, the first infoCell (second UITableView row) should display the first person object's data, right?
Then it seems you want:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *sessionCellID = #"sessionID";
static NSString *infoCellID = #"infoID";
if( indexPath.row == 0 ) {
SessionCellClass *cell = nil;
cell = (SessionCellClass *)[tableView dequeueReusableCellWithIdentifier:sessionCellID];
if( !cell ) {
// do something to create a new instance of cell
// either alloc/initWithStyle or load via UINib
}
// populate the cell with session model
return cell;
}
else {
InfoCellClass *cell = nil;
cell = (InfoCellClass *)[tableView dequeueReusableCellWithIdentifier:infoCellID];
if( !cell ) {
// do something to create a new instance of info cell
// either alloc/initWithStyle or load via UINib
// ...
// get the model object:
myObject *person = [[self people] objectAtIndex:indexPath.row - 1];
// populate the cell with that model object
// ...
return cell;
}
}
and you need to return [[self people] count] + 1 for the row count:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [[self people] count] + 1;
}
so that the n'th row shows the (n-1)th data.
if you look at the if else section it shows that the first row is an "sessionCell" and all other rows are "infoCells" what i think you want to do is make the first row an sessionCell, the second row an infoCell and all of the other rows peopleCells
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [self.people count] + 2; // Added two for sessionCell & infoCell
}
//inside cellForRowAtIndexPath
if(indexPath.row == 0) {
cell = [tableView dequeueReusableCellWithIdentifier:#"sessionCell"];
} else if (indexPath.row == 1 {
cell = [tableView dequeueReusableCellWithIdentifier:#"infoCell"];
} else {
cell = [tableView dequeueReusableCellWithIdentifier:#"personCell"];
Person *person = [self.people objectAtIndex:index.path.row - 2];
}
...
return cell;
Better yet, I would try to make two different sell sections, one for info and one for people
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 2;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return section == 0 ? 2 : self.people.count
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell = nil;
if (indexPath.section == 0) {
if(indexPath.row == 0) {
cell = [tableView dequeueReusableCellWithIdentifier:#"sessionCell"];
// configure session cell
} else if (indexPath.row == 1 {
cell = [tableView dequeueReusableCellWithIdentifier:#"infoCell"];
// configure info cell
}
} else {
cell = [tableView dequeueReusableCellWithIdentifier:#"infoCell"];
Person *person = [self.people objectAtIndexPath:indexPath.row];
// configure person cell
}
return cell;
}

Push a new view when a cell is tapped in Table View

Hey guys,
I have a Table View that has been populated with 21 data:
- (void)viewDidLoad {
self.title = NSLocalizedString(#"Glossary", #"Back");
NSMutableArray *array = [[NSArray alloc] initWithObjects:#"Title", #"Meta Description Tag", #"Meta Keywords", #"Headings", #"Images", #"Frames", #"Flash Contents", #"Charset", #"Favicon", #"W3C Compatibility", #"Page Rank", #"Alexa Rank", #"Indexed Pages", #"Latest Date Cached By Google", #"Backlinks", #"Dmoz Listing", #"Server Info", #"IP", #"Location", #"Server Type", #"Registrar Info", nil];
self.glossaryArray = array;
[array release];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
// Return the number of sections.
return 4;
}
// Category
- (NSString *)tableView:(UITableView *)tableView
titleForHeaderInSection:(NSInteger)section
{
if (section == 0) return #"In-Site SEO";
if (section == 1) return #"Inside Analysis";
if (section == 2) return #"Ranks N Stuff";
if (section == 3) return #"Server Info";
return #"Other";
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
// Return the number of rows in the section.
if (section == 0) return 7;
if (section == 1) return 3;
if (section == 2) return 6;
if (section == 3) return 5;
return 0;
}
// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
// Configure the cell...
NSUInteger row = [indexPath row];
if ( indexPath.section == 1 ) row += 7;
if ( indexPath.section == 2 ) row += 10;
if ( indexPath.section == 3 ) row += 16;
if ( indexPath.section == 4 ) row += 21;
cell.textLabel.text = [glossaryArray objectAtIndex:row];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
return cell;
}
Now this is the code I used to pussh a new view when a cell is tapped:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSInteger row = [indexPath row];
if (self.glossaryDetailViewController == nil) {
GlossaryDetailViewController *aGlossaryDetail = [[GlossaryDetailViewController alloc] initWithNibName:#"GlossaryDetailViewController" bundle:nil];
self.glossaryDetailViewController = aGlossaryDetail;
[aGlossaryDetail release];
}
glossaryDetailViewController.title = [NSString stringWithFormat:#"%#", [glossaryArray objectAtIndex:row]];
NewReferencemoi_caAppDelegate *delegate = (NewReferencemoi_caAppDelegate *)[[UIApplication sharedApplication] delegate];
[delegate.glossaryNavController pushViewController:glossaryDetailViewController animated:YES];
}
This code works perfectly, but the problem is that each and all 21 elements in my table view is opening the one and same nib file that I created. Basically, I want to create 1 UIViewController for each of my 21 elements, where each have their own description of the element, not just using 1 UIViewController for all elements in my Table View, and when each element has been tapped, each open their own view. Apparently, I don't know how to code in that part, so I hope someone can help me out with this part of my iPhone project, thanks
Please do not create 21 different view controllers just to show different items. Instead set a property on GlossaryDetailViewController that holds an instance of your data model item.
Consider this...
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSInteger row = [indexPath row];
if (self.glossaryDetailViewController == nil)
{
GlossaryDetailViewController *aGlossaryDetail = [[GlossaryDetailViewController alloc] initWithNibName:#"GlossaryDetailViewController" bundle:nil];
self.glossaryDetailViewController = aGlossaryDetail;
[aGlossaryDetail release];
}
glossaryDetailViewController.glossaryDetailItem = [glossaryArray objectAtIndex:row];
[self.navigationController pushViewController:self.glossaryDetailViewController animated:YES];
}
Using this approach makes GlossaryDetailViewController responsible for setting it's own data.
Edit
You'll also notice that I removed references to the app delegate. You don't need it to get access to the navigation controller. Each view controller in a navigation controller stack has a reference to it. While I'm thoroughly tearing your code apart, I would also factor out the creation of the view controller by overriding the getter for glossaryDetailViewController, like this:
- (GlossaryDetailViewController *)glossaryDetailViewController
{
if (!glossaryDetailViewController)
{
glossaryDetailViewController = [[GlossaryDetailViewController alloc] init];
}
return glossaryDetailViewController;
}
If you go this route, you can remove the if statement and just call self.glossaryDetailViewController.