Calling a New View by selecting a UITableView Row Error - iphone

I am having some issues with pulling up specific ViewControllers depending on which row is selected in my UITableView. I have a table, which contains 3 sections, with 4 rows in each section.
When a row is selected I have it set to call a new view for each row, so 12 views in total to be called depending on which row is selected. The issue is, that only the first 4 views are called, when I tap row number 5, it displays a new view, but it pulls up the first view.
I have set my UITableView up using the following code;
carbData = [[NSArray alloc] initWithObjects:#"What Are Carbs?",#"Why Do I Need Carbs?",#"Simple Vs. Complex",#"Fun Five Facts",nil];
proteinData = [[NSArray alloc] initWithObjects:#"What is Protein?",#"Why Do I Need Protein?",#"Complete Vs. Incomplete",#"Fun Five Facts",nil];
fatData = [[NSArray alloc] initWithObjects:#"What Are Fats?",#"Why Do I Need Fats?",#"Saturated Vs. Unsaturated",#"Fun Five Facts",nil];
[self setTitle:#"Nutrition Table"];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 3;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [self.carbData count];
return [self.proteinData count];
return [self.fatData count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *SimpleTableIdentifier = #"SimpleTableIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier: SimpleTableIdentifier];
if (cell == nil) { cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:SimpleTableIdentifier] autorelease];
}
if(indexPath.section == 0)
cell.text = [carbData objectAtIndex:indexPath.row];
if(indexPath.section == 1)
cell.text = [proteinData objectAtIndex:indexPath.row];
if (indexPath.section == 2)
cell.text = [fatData objectAtIndex:indexPath.row];
return cell;
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section{
if(section == 0)
return #"Carbohydrates";
if (section ==1)
return #"Protein";
else if (section ==2)
return #"Fats";
}
I then use the following code to determine which view is to be called, when a certain row is selected;
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
if ([[carbData objectAtIndex:indexPath.row] isEqual:#"What Are Carbs?"]) {
CarbsView1 *controller = [[CarbsView1 alloc] initWithNibName:#"CarbsView1" bundle:nil];
controller.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[self presentModalViewController:controller animated:YES];
[controller release];
}
if ([[carbData objectAtIndex:indexPath.row] isEqual:#"Why Do I Need Carbs?"]) {
CarbsView2 *controller = [[CarbsView2 alloc] initWithNibName:#"CarbsView2" bundle:nil];
controller.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[self presentModalViewController:controller animated:YES];
[controller release];
}
if ([[carbData objectAtIndex:indexPath.row] isEqual:#"Simple Vs. Complex"]) {
CarbsView3 *controller = [[CarbsView3 alloc] initWithNibName:#"CarbsView3" bundle:nil];
controller.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[self presentModalViewController:controller animated:YES];
[controller release];
}
if ([[carbData objectAtIndex:indexPath.row] isEqual:#"Fun Five Facts"]) {
CarbsView4 *controller = [[CarbsView4 alloc] initWithNibName:#"CarbsView4" bundle:nil];
controller.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[self presentModalViewController:controller animated:YES];
[controller release];
}
if ([[proteinData objectAtIndex:indexPath.row] isEqual:#"What is Protein?"]) {
ProteinView1 *controller = [[CarbsView4 alloc] initWithNibName:#"ProteinView1" bundle:nil];
controller.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[self presentModalViewController:controller animated:YES];
[controller release];
}
The app compiles and builds fine, everything works as i'd like it too, however when looking at the titles used, when I try and select "What is Protein?" is pulls up the view for "what are Carbs?" which is in the first if statement.
Any help would be massively appreciated

"What is Protein?" is in section 1, row 0. "What are Carbs?" is in section 0, row 0. Notice that your didSelectRowAtIndexPath method, you don't check the section number anywhere. So when you tap section 1, row 0, your first if statement returns true. I think you want something more like:
if (indexPath.section == 0) {
if(indexPath.row == 0) {
//present appropriate view controller
} else if (indexPath.row == 1) {
} else if (indexPath.row == 2) {
} ...
} else if (indexPath.section == 1) {
if (indexPath.row == 0) {
} else if (indexPath.row == 1) {
} ...
} ...

Related

How to display the DetailView after a search

I use predicate to filter a table.
It works very well and also to display the detailView for each cell.
But after a filtering it does not work to display the filtered list in the detailView.
The cell just turns blue when pressing it but does not shift to detailView.
What am I missing here?
The code looks like this.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
DetailViewController *dvController = [[DetailViewController alloc] initWithNibName:#"DetailViewController" bundle:nil];
Person *person;
if (tableView == self.searchDisplayController.searchResultsTableView)
{
person = [self.filteredPeople objectAtIndex:indexPath.row];
}
else
{
person = [self.people objectAtIndex:indexPath.row];
}
dvController.title = person.firstName;
dvController.price = person.sjuName;
dvController.link = person.sexName;
dvController.picture = [UIImage imageNamed:person.femName];
[self.navigationController pushViewController:dvController animated:YES];
[dvController release];
dvController = nil;
}
Here both the tableView are of different class so the can't be equal thus change your if condition as
if ([tableView class] != [UITableView class]) // if it's is of type UISearchResultsTableView
{
person = [self.filteredPeople objectAtIndex:indexPath.row];
}
else
{
person = [self.people objectAtIndex:indexPath.row];
}

Select certain row in one of the selections in a table view

I create a table with two sections. Each section has four cells.I want to push to a new view by navigation controller when a certain cell is pressed by user.
However there are two sections. I don't know how to distinguish the cell selected belongs to which section in
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
Please give me some tips. Thank you very much.
Here's my TableViewController.m
#import "TableViewController.h"
#import "LondonController.h"
#import "NewYorkViewController.h"
#import "ParisViewController.h"
#import "TokyoViewController.h"
#implementation TableViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
}
return self;
}
- (void)dealloc
{
[super dealloc];
[tableDataSource release];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
}
#pragma mark - View lifecycle
- (void)viewDidLoad
{
[super viewDidLoad];
UITableView *table = [[UITableView alloc]initWithFrame:CGRectMake(0, 0, 320, 460) style:UITableViewStyleGrouped];
[table setDataSource:self];
[table setDelegate:self];
tableDataSource = [[NSMutableArray alloc]init];
NSMutableArray* sec1 = [[NSMutableArray alloc] init];
[sec1 addObject:#"London"];
[sec1 addObject:#"New York"];
[sec1 addObject:#"Paris"];
[sec1 addObject:#"Tokyo"];
[tableDataSource addObject:sec1];
[sec1 release];
NSMutableArray* sec2 = [[NSMutableArray alloc] init];
[sec2 addObject:#"Elton John"];
[sec2 addObject:#"Michael Jackson"];
[sec2 addObject:#"Little Prince"];
[sec2 addObject:#"SMAP"];
[tableDataSource addObject:sec2];
[sec2 release];
[self.view addSubview:table];
[table release];
}
- (void)viewDidUnload
{
[super viewDidUnload];
}
- (BOOL)shouldAutorotateToInterfaceOrientation: (UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
#pragma mark - Table
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
if ( tableDataSource == nil )
return 1;
return [tableDataSource count];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
NSInteger bucketCount = -1;
NSObject *target_section;
if ( tableDataSource == nil )
return 0;
if( ( bucketCount = [tableDataSource count] ) < 1 || bucketCount <= section || (target_section = [tableDataSource objectAtIndex:section ]) == nil )
return 0;
return [ (NSMutableArray*)target_section count ];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier: [NSString stringWithFormat:#"Cell %i",indexPath.section]];
if (cell == nil)
{
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:[NSString stringWithFormat:#"Cell %i",indexPath.section]] autorelease];
}
cell.textLabel.text = (NSString*)[ (NSMutableArray*)[tableDataSource objectAtIndex:indexPath.section] objectAtIndex:indexPath.row];
return cell;
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
if(section == 0)
{
return #"City";
}
else if(section == 1)
{
return #"Person";
}
else
{
return #"Nothing;
}
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if (indexPath.row == 0)
{
LondonViewController *londonViewController = [[LondonViewController alloc] initWithNibName:#"LondonViewController" bundle:nil];
taipeiViewController.title = #"London Info";
[self.navigationController pushViewController:londonViewController animated:YES];
[londonViewController release];
}
else if (indexPath.row == 1)
{
NewYorkViewController *newYorkViewController = [[NewYorkViewController alloc] initWithNibName:#"NewYorkViewController" bundle:nil];
newYorkViewController.title = #"New York Info";
[self.navigationController pushViewController:newYorkViewController animated:YES];
[newYorkViewController release];
}
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}
#end
In
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
you should check indexPath.section value to determine the section of the selected cell.
refer a NSIndexpath reference: http://developer.apple.com/library/ios/#documentation/Cocoa/Reference/Foundation/Classes/NSIndexPath_Class/Reference/Reference.html
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSUInteger section = indexPath.section;
NSUInteger row = indexPath.row;
if (section == 0)
{
LondonViewController *londonViewController = [[LondonViewController alloc] initWithNibName:#"LondonViewController" bundle:nil];
taipeiViewController.title = #"London Info";
[self.navigationController pushViewController:londonViewController animated:YES];
[londonViewController release];
}
else if (section == 1)
{
NewYorkViewController *newYorkViewController = [[NewYorkViewController alloc] initWithNibName:#"NewYorkViewController" bundle:nil];
newYorkViewController.title = #"New York Info";
[self.navigationController pushViewController:newYorkViewController animated:YES];
[newYorkViewController release];
}
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}

iPhone UITableView Sections

I have been programming a UITableView and each cells pushes a new view, All I Want to do is add two new sections one male and one female, first and second voice need to be in the male section and the third voice needs to be in the female section.
#import "FirstLevelViewController.h"
#import "SecondLevelViewController.h"
#import "DisclosureDetailController.h"
#import "SecondVoiceController.h"
#import "ThirdVoiceController.h"
#implementation FirstLevelViewController
#synthesize controllers;
-(void)viewDidLoad {
self.title = #"Voices";
NSMutableArray *male = [[NSMutableArray alloc] init];
DisclosureDetailController *th = [DisclosureDetailController alloc];
th.title = #"First Voice";
[male addObject:th];
[th release];
SecondVoiceController *array2 = [SecondVoiceController alloc];
array2.title = #"Second Voice";
[male addObject:array2];
[array2 release];
ThirdVoiceController *array3 = [ThirdVoiceController alloc];
array3.title = #"Third Voice";
[male addObject:array3];
[array3 release];
self.controllers = male;
[male release];
[super viewDidLoad];
}
-(void)viewDidUnload {
self.controllers = nil;
[super viewDidUnload];
}
-(void)dealloc {
[controllers release];
[super dealloc];
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [self.controllers count];
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *FirstLevelCell= #"FirstLevelCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:FirstLevelCell];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:FirstLevelCell] autorelease];
}
NSUInteger row = [indexPath row];
SecondLevelViewController *controller = [controllers objectAtIndex:row];
cell.textLabel.text = controller.title;
cell.imageView.image = controller.rowImage;
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
return cell;
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSUInteger row = [indexPath row];
SecondLevelViewController *nextViewController = [self.controllers
objectAtIndex:row];
[self.navigationController pushViewController:nextViewController animated:YES];
}
All I Want to do is add two new sections one male and one female, first and second voice need to be in the male section and the third voice needs to be in the female section. Please help been stuck on this for a while!
The tableView delegate has a method called numberOfSectionsInTableView. Return the number of sections that you want to create.
Then, in the cellForRowAtIndexPath use indexPath's other property [indexPath section] to segregate rows based on sections.
An example
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 2; //one male and other female
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
switch(section){
case 0:
return [male count];
break;
case 1:
return [female count];
break;
}
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *FirstLevelCell= #"FirstLevelCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:FirstLevelCell];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:FirstLevelCell] autorelease];
}
SecondLevelViewController *controller;
switch([indexPath section]){
case 0:
controller = [male objectAtIndex: [indexPath row] ];
break;
case 1:
controller = [female objectAtIndex: [indexPath row] ];
break;
}
cell.textLabel.text = controller.title;
cell.imageView.image = controller.rowImage;
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
return cell;
}
Hows this?
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
// Return the number of sections.
return 2;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
// Return the number of rows in the section.
switch (section) {
case 0:
return # of rows in section;
break;
case 1:
return # of rows in section;
break;
}
return 0;
}

dismissModalViewControllerAnimated crashes app

I am new to iPhone development, so please pardon my ignorance.
I call a UIViewController from a UIViewController. The first UIViewController is a list of items, and the second is the detail for each of the items.
ListViewController (first UIViewController):
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
// initialize a AddViewController
selItem = indexPath.row;
selIndexPath = indexPath;
AddViewController *controller = [[AddViewController alloc] init];
// give controller the data to display
// show the AddViewController
[controller setData:[list objectAtIndex:indexPath.row]];
controller.delegate = self;
[self presentModalViewController:controller animated:YES];
[controller release]; // release the controller AddViewController
} // end method tableView:didSelectRowAtIndexPath:
In the 'AddViewController' I have a segment control as both the left and right button bars. On the left, I have 'Exit' and 'Delete'. On the right I have 'Add' and 'Save'. The outlets that the segment controls are linked to are:
AddViewController (second UIViewController):
- (IBAction)delExitSegment:sender
{
// The segmented control was clicked, handle it here
UISegmentedControl *segmentedControl = (UISegmentedControl *)sender;
switch (segmentedControl.selectedSegmentIndex) {
case 0: // Exit Button
[delegate addViewControllerDidExit:self];
break;
case 1: // Delete Button
[delegate addViewControllerDelItem:self];
break;
}
}
- (IBAction)segmentAction:sender
{
// The segmented control was clicked, handle it here
UISegmentedControl *segCtl = (UISegmentedControl *)sender;
switch (segCtl.selectedSegmentIndex) {
case 0: // Add Button
if (currentCell != nil)
[data setValue:currentCell.textField.text forKey:currentCell.label.text];
[delegate addViewControllerDidFinishAdding:self];
break;
case 1: // Save Button
[delegate addViewControllerUpdate:self];
break;
}
}
When I come back to my first view controller, I have:
ListViewController:
- (void)addViewControllerDidFinishAdding:(AddViewController *)controller
{
NSDictionary *item = [controller values];
if (item != nil)
{
[list addObject:item];
}
[self dismissModalViewControllerAnimated:YES];
[list writeToFile:itemFilePath atomically:NO];
[self calcTotal];
[self.tableView reloadData];
}
- (void)addViewControllerUpdate:(AddViewController *)controller
{
NSDictionary *item = [controller values];
if (item != nil)
{
[list replaceObjectAtIndex:selItem withObject:item];
}
[self dismissModalViewControllerAnimated:YES];
[list writeToFile:itemFilePath atomically:NO];
[self calcTotal];
[self.tableView reloadData];
}
- (void)addViewControllerDidExit:(AddViewController *)controller
{
[self dismissModalViewControllerAnimated:YES];
[self.tableView reloadData];
}
- (void)addViewControllerDelItem:(AddViewController *)controller
{
NSDictionary *item = [controller values];
if (item != nil)
{
[list removeObjectAtIndex:selItem];
[self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:selIndexPath] withRowAnimation:UITableViewRowAnimationFade];
[list writeToFile:itemFilePath atomically:NO];
}
[self dismissModalViewControllerAnimated:YES];
[self.tableView reloadData];
}
If I exit or delete an item from AddViewController, I have no problems. When I try and add or save, then my application will crash. The debugger crashes at dismissModalViewControllerAnimated. I can't see what's different between the two segment controls.
Any ideas what I may have wrong?
I just discovered that neither the left or right buttons work when I attempt to edit a cell. The editing cell in AddViewController is as follows:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *identifier = #"EditableCell";
EditableCell *cell = (EditableCell *)[table dequeueReusableCellWithIdentifier:identifier];
if (cell == nil)
{
cell = [[EditableCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier];
}
NSString *key = [fields objectAtIndex:indexPath.row + indexPath.section * 3];
[cell setLabelText:key];
cell.textField.text = [data valueForKey:key];
if (indexPath.section == 0 && (indexPath.row == 1 || indexPath.row == 3))
cell.textField.keyboardType = UIKeyboardTypeNumberPad;
if (indexPath.section == 1)
cell.textField.keyboardType = UIKeyboardTypeNumberPad;
cell.editing = NO;
cell.delegate = self;
cell.selectionStyle = UITableViewCellSelectionStyleNone;
return cell;
}
Here is the problem:
[self dismissModalViewControllerAnimated:YES];
[self.tableView reloadData];
When you dismiss the view the value of self become unknown, accessing the tableview will definitely crash.
If you want to refresh the tableView just use [self.tableView reloadData] and don't dismiss the view.

How can you push a new view with a grouped table?

Ive been trying to push a new view when a cell is tapped but absolutely nothing happens. I figured grouped style pushed the same as plain. Here is my code:
-(void)viewDidLoad {
[super viewDidLoad];
contactArray = [[NSArray alloc] initWithObjects:#"iPhone",#"iPod",#"MacBook",#"MacBook Pro",nil];
shareArray = [[NSArray alloc] initWithObjects:#"Flex",#"AIR",#"PhotoShop",#"Flash",nil];
}
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 2;
}
// Customize the number of rows in the table view.
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
if(section == 0)
return [contactArray count];
else
return [shareArray count];
}
-(NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section{
if(section == 0){
return #"Contact";
}else{
return #"Share";
}
}
-(NSString *)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section{
if(section == 0){
return #"Footer for Apple Products";
}else{
return #"Footer for Adobe Softwares";
}
}
// 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] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease];
}
// Set up the cell...
if(indexPath.section == 0){
cell.text = [contactArray objectAtIndex:indexPath.row];
}else{
cell.text = [shareArray objectAtIndex:indexPath.row];
}
return cell;
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
//NextViewController *nextController = [[NextViewController alloc] initWithNibName:#"NextView" bundle:nil];
//[self.navigationController pushViewController:nextController animated:YES];
if([contactArray objectAtIndex:indexPath.row] == #"iPhone"){
LandscapeHydrogen *abo = [[LandscapeHydrogen alloc] initWithNibName:#"LandscapeHydrogen" bundle:nil];
[self.navigationController pushViewController:abo animated:NO];
[abo release];
}
}
Any help is appreciated.
You could put a breakpoint at the didSelectRowAtIndexPath to see if the if statement is true.
Try changing
if([contactArray objectAtIndex:indexPath.row] == #"iPhone"){
to
if([[contactArray objectAtIndex:indexPath.row] isEqualToString:#"iPhone"]){
YourNextViewController * nextViewController = [[YourNextViewController alloc] initWithNibName: #"YourNextViewController" bundle: nil];
switch (indexPath.section) {
case 0:
nextViewController.title = [_contactArray objectAtIndex: [indexPath row]];
break;
case 1:
nextViewController.title = [_shareArray objectAtIndex: [indexPath row]];
break;
default:
break;
}
[[self navigationController] pushViewController:nextViewController animated:YES];
}
Solved with
else if (indexPath.section == 1 & indexPath.row == 0){
FaceBook *nextController = [[FaceBook alloc] initWithNibName:#"FaceBook" bundle:nil];
[self.navigationController pushViewController:nextController animated:YES];