Push a new view when a cell is tapped in Table View - objective-c

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.

Related

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

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

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

Displaying two sections of specific size in a table view

I am trying to fill a table view with an array, but I want two sections, and in the first section I want to display the imformation from indexpath.row == 0 to indexpath.row == 4 and in the second section the information from indexpath.row == 5 to indexpath.row == 9. How can I do that? I have this code for the second section:
if (indexPath.section == 1){
static NSString *CellIdentifier = #"LazyTableCell";
static NSString *PlaceholderCellIdentifier = #"PlaceholderCell";
int nodeCount = [self.entries count];
UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:CellIdentifier];
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle
reuseIdentifier:CellIdentifier] autorelease];
if (nodeCount > 0)
{
if (indexPath.row > 4) {
AppRecord *appRecord = [self.entries objectAtIndex:indexPath.row];
cell.textLabel.text = appRecord.artist;
cell.detailTextLabel.text = appRecord.appName;
if (!appRecord.appIcon)
{
if (self.tableView.dragging == NO && self.tableView.decelerating == NO)
{
[self startIconDownload:appRecord forIndexPath:indexPath];
}
cell.imageView.image = [UIImage imageNamed:#"Placeholder.png"];
}
else
{
UIImage *image = appRecord.appIcon;
CGSize itemSize = CGSizeMake(83.0, 48.0);
UIGraphicsBeginImageContext(itemSize);
CGRect imageRect = CGRectMake(0.0, 0.0, 83.0, 48.0);
[image drawInRect:imageRect];
appRecord.appIcon = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
cell.imageView.image = appRecord.appIcon;
}
}
return cell;
}
}
set the number of section in this function
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 2;
}
Perhaps you also want to implement
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
return #"section title";
}
set the number of lines in the following function
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return 5; // since you have 0-4 and 5-9 for the two sections
}
after seeing in your code [self.entries objectAtIndex:indexPath.row];
I assumed self.entries is the one array that you have been talking about.
You can initialize the UITableViewCell property in
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
by using a combination of section and row to get the index of your self.entries, probably something like
AppRecord *appRecord = [self.entries objectAtIndex:indexPath.row+5*indexPath.section];
I hope i got your question right.

Opening incorrect nib file with corresponding object in Table View

Hey guys,
I'm implementing a Table View into my project. First I populated my table, then I manage to successfully create 4 categories and give a number of rows in each of those categories, but here's my problem. The first category (which has 7 objects) is working fine when each data in that category opens their own nib files. But on the second category which has 3 objects, the 3 objects are actually opening nib files from the first category, which is not what I want. I created and assigned each objects in my Table View their own nib files to open, but like I said the objects from the second and also the third and fourth categories are opening the nib files from the first category. Here's my code how I separate the objects in my Table View:
#pragma mark -
#pragma mark Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
// Return the number of sections.
return 4;
}
// Category
- (NSString *)tableView:(UITableView *)tableView
titleForHeaderInSection:(NSInteger)section
{
if (section == 0) return #"Category 1";
if (section == 1) return #"Category 2";
if (section == 2) return #"Category 3";
if (section == 3) return #"Category 4";
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;
}
and to open each cell:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[tableView deselectRowAtIndexPath:indexPath animated:YES];
if ([[glossaryArray objectAtIndex:indexPath.row] isEqual:#"First View Controller"]) {
FirstViewController *firstVC = [[FirstViewController alloc] initWithNibName:#"FirstViewController" bundle:nil];
[self.navigationController firstVC animated:YES];
[firstVC release];
}
else if ([[glossaryArray objectAtIndex:indexPath.row] isEqual:#"Second View Controller"]) {
SecondViewController *secondViewController = [[SecondViewController alloc] initWithNibName:#"SecondViewController" bundle:nil];
[self.navigationController pushViewController:secondViewController animated:YES];
[secondViewController release];
}
else if (...
So that's pretty much how my nib files are opening each view, but like again, the problem is that they are not opening their own views, they are opening the nib files from the first category, which is the incorrect nib files. Sop I hope someone can help me figure out this problem, thanks
I believe your problem is that you are trying to map a 2 dimensional array onto a 1 dimensional array.
In your didSelectRowAtIndexPath: you are using indexPath.row, without checking to see what indexPath.section you are in. The row is 0 based on the section, not absolute to the number of rows in your table view. So you end up with something like
Section 0
Row 0
Row 1
Section 1
Row 0
Row 1
Here is the documentation on the NSIndexPath UIKit additions:
http://developer.apple.com/library/ios/#documentation/UIKit/Reference/NSIndexPath_UIKitAdditions/Reference/Reference.html#//apple_ref/doc/uid/TP40007175
It looks like your glossaryArray attempts to fix this by using an absolute index, so Section 1, Row 1 becomes index 3 into glossaryArray. What is happening though is indexPath.row is returning 1, instead of your expected 3.
You'll have to map the 2 dimensional indexPath onto one dimension or update your glossaryArray to be 2 dimensional.

Each data opening their own nib files in Table View

Hey guys,
I have a Table View sorted out properly, but I have a problem, each data on my Table View is opening the one and same nib file when I'm using this code:
- (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;
}
- (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];
}
GlossaryDetailViewController is my implementation file and also I added the nib file for that,
So hopefully someone can help me how to have each data open their own view, I won't really mind if I have to make a nib file for each and all my data on my Table View,
thanks
To put in your code style you can try
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSInteger row = [indexPath row];
NSString *nibName;
if ( indexPath.section == 1 ) nibName = #"firstNib";
if ( indexPath.section == 2 ) nibName = #"secondNib";
if ( indexPath.section == 3 ) nibName = #"thirdNib";
if ( indexPath.section == 4 ) nibName = #"fourthNib";
GlossaryDetailViewController *aGlossaryDetail = [[GlossaryDetailViewController alloc] initWithNibName:nibName 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];
}