iphone table view mixing up items in sections - iphone

i have the following item to display in my table
redFlowers = [[NSMutableArray alloc] init];
[redFlowers addObject:#"red"];
and this is the way this array is supposed to be shown
#define sectionCount 2
#define redSection 0
#define blueSection 1
#synthesize tableFavoritesData, tableView, favoritesArray, redFlowers;
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return sectionCount;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
switch (section) {
case redSection:
return [redFlowers count];
case blueSection:
return [tableFavoritesData count];
}
}
-(NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
switch (section) {
case redSection:
return #"Refresh";
case blueSection:
return #"Favorites";
}
}
// 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];
}
switch (indexPath.section)
{
case redSection:
cell.textLabel.text =[redFlowers objectAtIndex:indexPath.row];
case blueSection:
cell.textLabel.text = [tableFavoritesData objectAtIndex: indexPath.row];
}
return cell;
when i load my table it doesnt show at all the "red cell" from the redFlowers array but it shows the ones from tableFavoritesdata inside that section.

switch (indexPath.section)
{
case redSection:
cell.textLabel.text =[redFlowers objectAtIndex:indexPath.row];
break; // <--
case blueSection:
cell.textLabel.text = [tableFavoritesData objectAtIndex: indexPath.row];
break; // <--
}
If you don't break, the red section case will fall through to the blue section case.

Related

EXE Bad Access when Scrolling UITableView - iPhone

I have a simple UITableView with 9 cells. When I move the table up or down by scrolling, I get EXE bad access. NSZombieMode points at the cellForRowAtIndexMethod.
- (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];
}
cell.textLabel.text = [lineArray objectAtIndex:indexPath.row];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
return cell;
}
Can anyone suggest what is wrong ?
If ARC is disabled then add autorelease when you create cell
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:CellIdentifier] autorelease];
This can be the reason of the leaks. Check also lineArray since it used like ivar and probably this array was released at some point.
My guess is you're trying to access an element in your lineArray that is out of bounds.
IE: indexPath.row is returning a 6 when you only have 3 elements in your lineArray.
It's occurring when you scroll down as it triggers cellForRowAtIndexPath to be called on higher number rows (rows that with indexPath.row > 3 for example)
I'll go one more step and guess that you're probably statically returning numberOfRowsForSection.
Setting it to lineArray.count should fix it.
According to my understanding :-
1) in the lineArray you have some 9 items but in the numberOfRowsInSection you are returning the rowCount more than the items in the array and so it crashes and points to ceelForRowAtIndex.
2) Here is the sample code for your understanding :-
- (void)viewDidLoad
{
[super viewDidLoad];
lineArray = [[NSMutableArray alloc]initWithObjects:#"1",#"2",#"3",#"4",#"5", nil];
tableView1 = [[UITableView alloc]init];
tableView1.delegate = self;
tableView1.dataSource = self;
tableView1 .frame =self.view.frame;
[self.view addSubview:tableView1];
}
- (void)viewDidUnload
{
[super viewDidUnload];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [lineArray count];
//return ;
}
- (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];
}
cell.textLabel.text = [lineArray objectAtIndex:indexPath.row];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
return cell;
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
}

How to add Section and TableView Cell dynamically

I have a button that when pressed, a tableview section will be added and will also add a new row to that section. How can I implement this programatically?
I have an array of cells.
Here are my codes
- (IBAction)addCell:(id)sender {
UITableViewCell *newCell = [[UITableViewCell alloc] init];
counter++;
[cells addObject:newCell];
[self.tableView reloadData];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return [cells count];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return 1;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
//this is where i want to adjust the row per section
//this code hide the recent sections, only the current created section appears
return [cells objectAtIndex:indexPath.row];
}
Hi try reading this:
How to display the UITableView programmatically?
Adding cells programmatically to UITableView
Hope this could help you.
First, update your's datamodel(NSArray or mutable). Second, when you want tableview refresh, add a code [self.tableView reloadData];
oops, your code some strange uitaleviewDataSource, Delegate Method.
also, your have a some mistake.
why you implements numberOfRowsInSection return 1? very strange.
I apprecated below code.
CASE 1. No has DataModel.
- (IBAction)addCell:(id)sender
{
cellRowsCount++;
[self.tableView reloadData];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return cellRowsCount;
}
- (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];
}
return cell;
}
your codes, dataModel(NSArray or mutable) does not necessarily need, so I simply rowCount variable added and your rowsCount of tableviewCell has synchronized.
If you wanna with DataModel, below CASE2. refer plz.
CASE2. has DataModel.
- (IBAction)addCell:(id)sender
{
textCount ++;
NSString *cellText = [NSString stringWithFormat:"blah %d", textCount];
[myArray addObject:cellText];
[self.tableView reloadData];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return [myArray count];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [[myArray objectAtIndex:section] count];
}
- (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];
}
cell.textLabel.text = (NSString *)[myArray objectAtIndex:indexPath.row];
return cell;
}
You only have to add the new section and the new item to the array that holds the section and the items like so:
- (void)viewDidLoad
{
[super viewDidLoad];
animals = #{#"Section 1" : #[#"Item 1", #"Item 2", #"Item 3"],
#"Section 2" : #[#"Item 1", #"Item 2"]};
}
after that you just reload the tableView wherever your logic needs:
[self.tableView reloadData];

TalbeView cell showing null value

I have created a custom table for the rootViewController of a split view application so that the selected row expands and shows as a sub-table (showing main menu and sub menu ). The first row of the sub-table should show the particular main menu item of the sub-table.I'm fetching the main menu items from another class.
The problem is that the first row for the sub table is showing blank for me.Using NSLog, I checked the value of variable just before assigning it to the cell and even after assigning the value to the cell, i checked the text value in the cell using cell.textLabel.text. I'm getting the value in the console every time, but the row is still blank!!!
Row is showing the value if I'm hard coding it with any value!!!
Note:TableView is showing values for remaining rows.
Anybody can help me?? Thanks in advance...and sorry for my poor English..
EDIT: In the rootViewController:
(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
tableView.separatorColor=[UIColor grayColor];
if (sectionopen[indexPath.row]) {
accordianTable *cell1;
cell1=(accordianTable *)[tableView dequeueReusableCellWithIdentifier:#"cell1"];
if (cell1 == nil) {
cell1 = [[[accordianTable alloc] initWithFrame:CGRectZero reuseIdentifier:#"cell1"] autorelease];
}
cell1.selectionStyle=UITableViewCellSelectionStyleNone;
return cell1;
} else {
//tableView.separatorStyle = UITableViewCellSeparatorStyleSingleLine;
static NSString *CellIdentifier = #"CellIdentifier";
// Dequeue or create a cell of the appropriate type.
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
cell.selectionStyle = UITableViewCellSelectionStyleGray;
}
// Configure the cell.
cell.textLabel.text=[UIAppDelegate.mainMenu objectAtIndex:indexPath.row];
return cell;
}
}
(void)tableView:(UITableView *)aTableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
accordianTable *acc = [[accordianTable alloc]init];
acc.titl=[UIAppDelegate.mainMenu objectAtIndex:indexPath.row];
[acc.subTable reloadSections:[NSIndexSet indexSetWithIndex:0] withRowAnimation:UITableViewRowAnimationFade];
///turn them all off
sectionopen[0]=NO;
sectionopen[1]=NO;
sectionopen[2]=NO;
sectionopen[3]=NO;
///open this one
sectionopen[indexPath.row]=YES;
///animate the opening and expand the row
[self.tableView reloadSections:[NSIndexSet indexSetWithIndex:0] withRowAnimation:UITableViewRowAnimationFade];
UIViewController *localdetailViewController = nil;
}
In the custom cell class (accordianTable):
(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
// Number of rows is the number of time zones in the region for the specified section.
return [UIAppDelegate.subMenu count]+1;//including title and sub menu
}
(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *MyIdentifier = #"MyIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:MyIdentifier] autorelease];
}
switch (indexPath.row)
{
case 0:
NSLog(#"text is >> %#",titl);
cell.textLabel.text=titl;
NSLog(#"text is >> %#",cell.textLabel.text);
cell.textLabel.textColor=[UIColor whiteColor];
cell.contentView.backgroundColor=[UIColor blackColor];
cell.textLabel.backgroundColor=[UIColor blackColor];
cell.selectionStyle=UITableViewCellSelectionStyleNone;
break;
default:
int Row=indexPath.row;
Row--;
cell.textLabel.text=[UIAppDelegate.subMenu objectAtIndex:Row];
cell.textLabel.textColor=[UIColor orangeColor];
cell.textLabel.textAlignment=UITextAlignmentCenter;
cell.selectionStyle=UITableViewCellSelectionStyleNone;
break;
}
return cell;
}

Section receiving cell values of other section

I am trying to get the first five cards in one section and other five in next section of table view . Actually I have done parsing and unable to get proper cell values. The thing I am getting is combined values for example : in section = birthday cell values are card1, card2 and again card1, card 2 of new year section, and in other section same thing is repeating. What should I do to make grouped i.e card1, card 2 in birthday section and card1, card2 should be in new year section. Here is my code:
(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 2;
NSLog(#"section in rv");
}
(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [appDelegate.books count];
NSLog(#".....appDelegate.books count");
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSLog(#"cell for index path");
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease];
}
Book *aBook = [appDelegate.books objectAtIndex:indexPath.row];
NSLog(#"text for cell...");
cell.text = aBook.Subcatname;
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
return cell;
[appDelegate release];
}
Take a look at dks1725's response to set up the correct number of rows per section.
Also, and more directly in response to your question, in tableView:cellForRowAtIndexPath: for each table row you are always returning a cell with the same content, regardless of what section the cell is in. That's why you are getting the same content ('card1', 'card2' and so on) appearing in each section.
Keep in mind that the indexPath you are receiving in this method has two components: indexPath.rowand indexPath.section. You are ignoring the second of these, and so, for every section, you always return the same cell for a each row.
You will need to modify tableView:cellForRowAtIndexPath: so that a piece of it will look something like the following:
if (indexPath.section == 0) {
//Retrieve the content you want for each row in section 0
//It will look something like this, but will be different depending on where you stored your content
Book *aBook = [appDelegate.books objectAtIndex:indexPath.row];
cell.text = birthdayBook.Subcatname;
}
if (indexPath.section == 1) {
//Retrieve the content you want for each row in section 1
//It will look something like this, but will be different depending on where you stored your content
Book *aBook = [appDelegate.books objectAtIndex:indexPath.row + 5];
cell.text = newyearsBook.Subcatname;
}
...
The above is edited as per your comments.
Given your model, you could also do it in fewer lines, as follows:
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 2;}
-(NSString *)tableView:(UITableView *)tblView titleForHeaderInSection:(NSInteger)section {
NSString *sectionName = nil;
switch(section)
{
case 0:
sectionName = [NSString stringWithString:#"birthday"];
break;
case 1:
sectionName = [NSString stringWithString:#"new year"];
}
return sectionName;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
NSInteger count;
if(section == 0)
{ count=5; }
else if(section == 1)
{ count=5; }
return count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSLog(#"cell for index path");
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease];
}
NSLog(#"text for cell...");
if(indexPath.section == 0)
{
Book *aBook = [appDelegate.books objectAtIndex:indexPath.row];
cell.text = aBook.Subcatname;
}
else if(indexPath.section == 1)
{
Book *aBook = [appDelegate.books objectAtIndex:indexPath.row+5*indexPath.section];
cell.text = aBook.Subcatname;
}
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
return cell;
[appDelegate release];
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
// Navigation logic -- create and push a new view controller
if(bdvController == nil)
bdvController = [[BookDetailViewController alloc] initWithNibName:#"BookDetailView" bundle:[NSBundle mainBundle]];
NSLog(#"pushing to bdv controller");
if(indexPath.section == 0)
{
Book *aBook = [appDelegate.books objectAtIndex:indexPath.row];
bdvController.aBook = aBook;
}
else if(indexPath.section == 1)
{
Book *aBook = [appDelegate.books objectAtIndex:indexPath.row+5*indexPath.section];
bdvController.aBook = aBook;
}
NSLog(#"push to view descrip, id, pic url");
//bdvController.aBook = aBook;
NSLog(#"loop");
[self.navigationController pushViewController:bdvController animated:YES];
}
You have to set number of rows for each section something like below..
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if(indexPath.section==0)
//return no of rows for section 0
else
//return no of rows for section 1
}

UITableView only pushes to one controller

So I have my UITableView, with 2 sections and 1 cell in each, and if I click the first one, it works, then the second one, it goes to the first controller. RootViewController is a navigationController, trying to push to ViewControllers.
Here's the code for the tableView:
// Customize the number of sections in the table view.
- (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 1;
else
return 1;
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section{
if(section == 0){
return #"Terminal/SSH Guides";
}else{
return #"Cydia Tutorials";
}
}
// 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 = #"Changing Password for root";
} else {
cell.text = #"Hiding Sections";
}
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
id newController;
switch (indexPath.row) {
case 0:
newController = [[rootpassword alloc] initWithNibName:#"rootpassword" bundle:nil];
break;
case 1:
newController = [[hidingsections alloc] initWithNibName:#"hidingsections" bundle:nil];
break;
default:
break;
}
[self.navigationController pushViewController:newController animated:TRUE];
[tableView deselectRowAtIndexPath:indexPath animated:TRUE];
}
I'm also having trouble adding more sections and rows/cells to sections.
Thanks.
I believe you should do the switch in "didSelectRowAtIndexPath" over indexPath.section instead of indexPath.row since both sections have only one row.
You only have one row in each section, so indexPath.row will always be zero. In didSelectRowAtIndexPath you have to test the section not the row (presuming you intend to keep only one row per section).