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
}
Related
In my tableview i have 4 sections and i need to have 1 check mark in each section. Like so...
Section 0
row 0
row 1
row 2 /
row 3
Section 1
row 0
row 1 /
row 2
etc..
numberOfRowsInSection:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
NSInteger numberOfRows;
if (section == 0) {
numberOfRows = 3;
}
else if (section == 1) {
numberOfRows = 4;
}
else if (section == 2) {
numberOfRows = 4;
}
else if (section == 3) {
numberOfRows = 3;
}
return numberOfRows;
}
cellForRowAtIndexPath:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *userChoices = #"UserChoices";
cell = [tableView dequeueReusableCellWithIdentifier:userChoices];
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:userChoices];
if (indexPath.section == 0) {
cell.textLabel.text = [mail objectAtIndex:indexPath.row];
}
else if (indexPath.section == 1) {
cell.textLabel.text = [search objectAtIndex:indexPath.row];
}
else if (indexPath.section == 2) {
cell.textLabel.text = [social objectAtIndex:indexPath.row];
}
else if (indexPath.section == 3) {
cell.textLabel.text = [maps objectAtIndex:indexPath.row];
}
if([self.checkedIndexPath isEqual:indexPath])
{
cell.accessoryType = UITableViewCellAccessoryCheckmark;
}
else
{
cell.accessoryType = UITableViewCellAccessoryNone;
}
return cell;
}
didSelectRowAtIndexPath:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
// Uncheck the previous checked row
UITableViewCell* uncheckCell = [tableView cellForRowAtIndexPath:self.checkedIndexPath];
if(self.checkedIndexPath)
{
uncheckCell.accessoryType = UITableViewCellAccessoryNone;
}
if([self.checkedIndexPath isEqual:indexPath])
{
self.checkedIndexPath = nil;
}
else
{
UITableViewCell* cell = [tableView cellForRowAtIndexPath:indexPath];
cell.accessoryType = UITableViewCellAccessoryCheckmark;
self.checkedIndexPath = indexPath;
}
// use this to put checkmark on the item
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}
The following code gives me a check mark next to a cell within ALL sections of the table. Any body have any ideas?
You could use a dictionary to keep track of which row is checked on each section:
NSMutableDictionary *_checkedRowsDict = [NSMutableDictionary dictionaryWithCapacity:numberOfSections];
...
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
if ([_checkedRowsDict objectForKey:[NSNumber numberWithInt:indexPath.section]]) {
// Unmark the row found on _checkedRowsDict
NSNumber *num = [_checkedRowsDict objectForKey:[NSNumber numberWithInt:indexPath.section]];
int row = [num intValue];
NSIndexPath *checkIndexPath = [NSIndexPath indexPathForRow:row inSection:indexPath.section];
UITableViewCell *checkedCell = [tableView cellForRowAtIndexPath:checkIndexPath];
checkedCell.accessoryType = UITableViewCellAccessoryNone;
}
// Mark the selected row
UITableViewCell *selectedCell = [tableView cellForRowAtIndexPath:indexPath];
selectedCell.accessoryType = UITableViewCellAccessoryCheckmark;
// Update _checkedRowsDict
[_checkedRowsDict setObject:[NSNumber numberWithInt:indexPath.row] forKey:[NSNumber numberWithInt:indexPath.section]];
...
}
And something similar to initialize the rows on tableView:cellForRowAtIndexPath:
Make a NSMutableArray of NSNumbers that contain integer representations of the selected element within the sections that is represented by the element in the array.
You will have to do some more set up but when you check
if([self.checkedIndexPath isEqual:indexPath])
you can check
if([[yourArrayOfCheckedIndexes objectAtIndex:indexPath.section] integerValue] == indexPath.row)
Basically you need to store the checked index for every section
Try this, worked just fine for me:
-VARIABLES:
#property NSInteger checkedCellRow;
#property NSInteger checkedCellSection;
-FUNCTIONS:
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
if (checkedCellSection == indexPath.section)
{
if (checkedCellRow == indexPath.row)
{
cell.accessoryType = UITableViewCellAccessoryCheckmark;
}
else
{
cell.accessoryType = UITableViewCellAccessoryNone;
}
}
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
checkedCellRow = indexPath.row;
checkedCellSection = indexPath.section;
[myTable reloadData];
}
I add this to my viewDidLoad and all works fine. Thx.
-(void)viewDidLoad {
NSUInteger i = 2; //Number of section
NSMutableDictionary *_checkedRowsDict = [NSMutableDictionary dictionaryWithCapacity:i];
...
}
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).
I have a viewcontroller with a nib - which has a tableview, searchbar and searchdisplaycontroller inside.
The searchdisplaycontroller's contentscontroller, results delegate, delegate and results datasource is wired to the viewcontroller in IB. The searchbar's delegate is wired to the view controller in IB. The main tableview is also wired to the viewcontroller and its loading items during runtime properly.
Everything seems to work except the resultstableview - it never gets populated and the tableView:cellForRowAtIndexPath: never gets called AFTER the user types into the searchbar - it only gets called to populate the main tableview.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"CellIdentifier";
// Dequeue or create a cell o f the appropriate type.
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
if (tableView.tag == 2)
{
cell.accessoryType = UITableViewCellAccessoryDetailDisclosureButton;
// Configure the cell.
NSHotel *selectedHotel = [[self hotelList] objectAtIndex:[indexPath row]];
//Store the hotel id for use later
selectedHotel.id = [indexPath row];
//cell.textLabel.text = [NSString stringWithFormat:#"Catalonia Majorica", indexPath.row];
cell.textLabel.text = [selectedHotel name];
}
else if (tableView.tag == 1)
{
cell.accessoryType = UITableViewCellAccessoryNone;
// Configure the cell...
NSAirport *selectedAirport = nil;
if (tableView == self.searchDisplayController.searchResultsTableView)
{
selectedAirport = [self.filteredListContent objectAtIndex:indexPath.row];
}
else
{
selectedAirport = [self.listContent objectAtIndex:indexPath.row];
}
//Set the label of the cell formatting the distance from the device
cell.textLabel.text = [NSString stringWithFormat:#"%# - %# miles",
selectedAirport.name, [self formattedStringWithDecimal:selectedAirport.milesFromDevice]];
//Adjust the front of the label
cell.textLabel.font = [UIFont boldSystemFontOfSize:12];
}
return cell;
}
Fixed it - it was returning 0 here:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if (tableView == self.searchDisplayController.searchResultsTableView)
{
return [self.filteredListContent count];
}
else if (tableView.tag == 1)
{
return [self.listContent count];
}
else if (tableView.tag == 2)
{
// Return the number of rows in the section.
return [[self hotelList] count];
}
NSLog(#"The rows in tableview!");
return 0;
}
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.
I recently downloaded Apple's sample app CoreDataBooks and for the sake of learning decided to add a cell to the last record in the RootViewController.m table view, which would display the number of records that were fetched.
The code I added is shown below. I didn't get to the point of adding the fetch count because I am getting bad results from my code. If you download CoreDataBooks and replace the table view datasource methods with the code here you will see the following:
the new cell is added to the bottom of the table view.
when you scroll back to the top of the table another cell receives the formatting that is only supposed to be given to the last cell of the table. In my case, under the author section of 'Bill Bryson' the book title 'Notes From a Big Country' turns blue and is centered when you scroll back to the top of the table.
Any help in resolving this would be appreciated.
Here is the link for the sample app CoreDataBooks: link text
Here is the modified code for RootViewController.m:
/*
The data source methods are handled primarily by the fetch results controller
*/
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return [[fetchedResultsController sections] count] + 1;
}
// Customize the number of rows in the table view.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
if (section < [[fetchedResultsController sections] count])
{
id <NSFetchedResultsSectionInfo> sectionInfo = [[fetchedResultsController sections] objectAtIndex:section];
return [sectionInfo numberOfObjects];
}
return 1;
}
// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView*)tableViewcellForRowAtIndexPath:(NSIndexPath*)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
NSLog(#"indexPath.section: %i",indexPath.section);
if (indexPath.section < [[fetchedResultsController sections] count]){
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
// Configure the cell.
[self configureCell:cell atIndexPath:indexPath];
}
else{
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
cell.textLabel.text = (#"This is a NEW Cell...");
cell.textLabel.textAlignment = UITextAlignmentCenter;
cell.textLabel.textColor = [UIColor blueColor];
}
return cell;
}
- (void)configureCell:(UITableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath {
// Configure the cell to show the book's title
Book *book = [fetchedResultsController objectAtIndexPath:indexPath];
cell.textLabel.text = book.title;
}
- (NSString *)tableView:(UITableView *)tableView
titleForHeaderInSection:(NSInteger)section {
// Display the authors' names as section headings.
if (section < [[fetchedResultsController sections] count])
return [[[fetchedResultsController sections] objectAtIndex:section] name];
return #"";
}
That's all. Thank-you for your time.
I see two solutions:
Use a different cell identifier for your cell.
To do this, define a new cell identifier after the other and move the cell reuse code inside the two different cell cases:
static NSString *CellIdentifier = #"Cell";
static NSString* myCellIdentifier = #"MyCell"; // new cell identifier
// move inside two cell cases
// UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
NSLog(#"indexPath.section: %i",indexPath.section);
if (indexPath.section < [[fetchedResultsController sections] count]){
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; // only reuse this type of cell here
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
// Configure the cell.
[self configureCell:cell atIndexPath:indexPath];
}
else{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:myCellIdentifier]; // only reuse this type of cell here
if (cell == nil) {
2 . Override all of the applicable formatting when configuring the cells:
cell.textLabel.text = (#"This is a NEW Cell..."); // You are already overriding the only cell attribute that the book cell configures
cell.textLabel.textAlignment = UITextAlignmentCenter;
cell.textLabel.textColor = [UIColor blueColor];
}
return cell;
}
- (void)configureCell:(UITableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath {
// Configure the cell to show the book's title
Book *book = [fetchedResultsController objectAtIndexPath:indexPath];
cell.textLabel.text = book.title;
cell.textLabel.textAlignment = UITextAlignmentLeft; // I assume Left is the default alignment
cell.textLabel.textColor = [UIColor blackColor]; // I assume black is the default color
}