following code sets cell texts and add a checkMark only to last selected. Always only one cell check marked and works properly excepting when it is displayed for first time. So, text is not showed for that cell (only that one) until you press any other cell. For example, if cellPos = 4 when viewDidLoad, that cell will not contain text.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString* cellIdentifier = #"cellIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if(cell == nil)
{
cell = (UITableViewCell*) [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellIdentifier];
}
cell.accessoryType = UITableViewCellAccessoryNone;
if (indexPath.section == 0) {
if(indexPath.row == cellPos)
{
cell.accessoryType = UITableViewCellAccessoryCheckmark;
cell.selected = YES;
}
else
{
cell.accessoryType = UITableViewCellAccessoryNone;
cell.selected = NO;
}
switch (indexPath.row) {
case 0:
cell.textLabel.text = #"English";
cell.imageView.image = [UIImage imageNamed:#"english.png"];
break;
case 1:
cell.textLabel.text = #"Español";
cell.imageView.image = [UIImage imageNamed:#"spanish.png"];
break;
case 2:
cell.textLabel.text = #"Deutsch";
cell.imageView.image = [UIImage imageNamed:#"germany.png"];
break;
case 3:
cell.textLabel.text = #"Français";
cell.imageView.image = [UIImage imageNamed:#"french.png"];
break;
case 4:
cell.textLabel.text = #"Italiano";
cell.imageView.image = [UIImage imageNamed:#"italian.png"];
break;
default:
break;}
}
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
cellPos = indexPath.row;
[tableView reloadData];
}
Have you tried moving the if-else block after the switch block? This way you set the text of the cell before you set the cell to selected. The fact that it only occurs the first time suggests to me that it may be an order of operations problem.
Related
I am displaying certain information in a tableview. These are basically Exam rooms. I am using this logic in order to put the check marks for selecting the particular room. The code is as follows:
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath
*)indexPath {
static NSString *CellIdentifier = #"CellIdentifier";
// intializing tableview cell.
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:CellIdentifier] autorelease];
}
// Setting tableviewcell title from Room array.
cell.textLabel.text = [NSString stringWithFormat:#"%#",[[arr_roomList
objectAtIndex:indexPath.row] valueForKey:#"description"]];
/* checking the condition if checkedIndexPath is != null.
means at first time checkedIndexPath= null.*/
if (self.checkedIndexPath) {
/* checking the condition if current cell is selected then
we have to show the UITableViewCellAccessoryCheckmark (checkmark on right side of the
cell).*/
if([self.checkedIndexPath isEqual:indexPath])
{
cell.accessoryType = UITableViewCellAccessoryCheckmark;
}
else
{
cell.accessoryType = UITableViewCellAccessoryNone;
}
}
else{
if ([[[arr_roomList objectAtIndex:indexPath.row] valueForKey:#"resource_id"]
isEqualToString:self.str_selected_resourceId]) {
cell.accessoryType = UITableViewCellAccessoryCheckmark;
}
}
// This Method will set the Background and Selected Background Image for the cell.
[[AppDelegate sharedInstance] SetBackgroundImageForcell:cell];
if ([[[arr_roomList objectAtIndex:indexPath.row] valueForKey:#"rec_type"] isEqualToString:#"R"]) {
cell.backgroundColor = [UIColor grayColor];
}
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
[tableView deselectRowAtIndexPath:indexPath animated:YES];
/* checking the condition if checkedIndexPath is != null.
means at first time checkedIndexPath= null.*/
if(self.checkedIndexPath)
{
UITableViewCell* uncheckCell = [tableView
cellForRowAtIndexPath:self.checkedIndexPath];
uncheckCell.accessoryType = UITableViewCellAccessoryNone;
}
UITableViewCell* cell = [tableView cellForRowAtIndexPath:indexPath];
cell.accessoryType = UITableViewCellAccessoryCheckmark;
self.checkedIndexPath = indexPath;
[self changeRoomWithResourceId:[[arr_roomList objectAtIndex:indexPath.row]
valueForKey:#"resource_id"]];
}
As I am scrolling down the table the check marks are repeating themselves for any cell randomly. Please Help me as this issue is taking lot of time for me.
You have to clear out any checkmarks that might be placed already, because UITableView reuses cells and does not do it automatically:
// ...
if ([[[arr_roomList objectAtIndex:indexPath.row] valueForKey:#"resource_id"]
isEqualToString:self.str_selected_resourceId]) {
cell.accessoryType = UITableViewCellAccessoryCheckmark;
}
// add this
else
{
cell.accessoryType = UITableViewCellAccessoryNone;
}
following code works properly but it applies same cell text to all sections. How could I apply selection case also depending on section? Thank you.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = (UITableViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
}
switch (indexPath.row) {
case 0:
cell.textLabel.text = #"English";
break;
case 1:
cell.textLabel.text = #"Chinese";
break;
case 2:
cell.textLabel.text = #"Japanese";
break;
default:
break;
}
return cell;
}
You can use indexPath.section to get the section number, just like how you're using indexPath.row for the row number.
You have to check for the indexPath.section and also indexPath.row:
if (indexPath.section == 0) {
if (indexPath.row) {
...
}
} else if (indexPath.section == 1)
if (indexPath.row) {
...
}
} else if ...
I would like to get a TableView with different elements on the accessoryView, depending on the section. Everything works fine, but when I scroll down to section 2 and then scroll up again to section 0, the rows in section 0 have switchers. Could you please help me finding out what I'm doing wrong?
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSInteger sectionIndex = [indexPath section];
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
NSDictionary *dictionary;
NSArray *array;
NSString *cellValue;
UISwitch *switchView;
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
switch (sectionIndex) {
case 0:
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
break;
case 1:
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
break;
case 2:
switchView = [[UISwitch alloc] initWithFrame:CGRectZero];
cell.accessoryView = switchView;
[switchView setOn:NO animated:NO];
[switchView addTarget:self action:#selector(switchChanged:) forControlEvents:UIControlEventValueChanged];
[switchView release];
break;
default:
break;
}
dictionary = [searchArray objectAtIndex:indexPath.section];
array = [dictionary objectForKey:#"advancedSearch"];
cellValue = [array objectAtIndex:indexPath.row];
cell.textLabel.text = cellValue;
return cell;
}
You are dequeuing your table cells (cf. -[UITableView dequeueReusableCellWithIdentifier:]), which means that you are receiving table views that have already been allocated and possibly pre-populated with stale data. In case 0: and case 1: of your switch statement, you should add the following line:
cell.accessoryView = nil;
Use different cell identifiers for different cells.
Something like:
NSString *CellIdentifier;
switch ([indexPath row]) {
case 0: CellIdentifier = #"cell0";
break;
case 1: CellIdentifier = #"cell1";
break;
default: CellIdentifier = #"cell";
break;
}
Otherwise Xcode thinks that all your cells have the same look and tries to reuse them while you scroll.
The problem is from dequeueReusableCellWithIdentifier you must use different identifiers for different cells because you reuse them.
i am working on an iphone project that shows an artwork at the top tableview section (section 0) and shows a list of items in (section 1). the tableview looks like that:
section0:
ARTWORK IMAGE
section1:
cell1: text1
cell2: text2
.
.
. and so goe like that.
but strangely the program shows another imageview at the bottom of the page when i scroll down, but it shouldnt show that image because its not section 0.
heres the code for my program :
- (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 1;
break;
case 1:
return [diskArray count];
break;
default:
return 0;
break;
}
}
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
switch (indexPath.section) {
case 0:
return 225;
break;
default:
return 44;
break;
}
}
// 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...
if(indexPath.section == 0)
{
if(indexPath.row == 0)
{
NSLog(#"adding image to the cell");
UIImage *img = [UIImage imageNamed:#"artwork.jpeg"];
UIImageView *imgView = [[UIImageView alloc] initWithFrame:CGRectMake(47, 0, 225, 225)];
imgView.image = img;
[cell addSubview:imgView];
[imgView release];
cell.backgroundColor = [UIColor clearColor];
cell.textLabel.text = nil;
}
}
else if(indexPath.section == 1){
cell.textLabel.text = [diskArray objectAtIndex:indexPath.row];
cell.backgroundColor = [UIColor darkGrayColor];
cell.textLabel.textColor = [UIColor whiteColor];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
}
return cell;
}
The iPhone reuses old cells with the subview you've added. Try changing the CellIdentifier for each section.
It's because you reuse the cell, but nowhere it is reinitialized.
try this to remove the image :
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
} else {
[cell subviews] makeObjectsPerformSelector:#selector(removeFromSuperview)];
//you should also reinit the other values, as textLabel, bgColor et al.
}
I am writing a UITableView that contains 2 sections. When the table first loads all the cells are displaying the correct info, but when I start scrolling up and down, cells detailedTextLabel and accessoryType are being refreshed incorrectly, such that some cells that should only contain a detailedTextLabel also contain an accessory, and cells that should only contain an accessory also contain a detailedTextLabel.
Inside cellForRowAtIndexPath: I am using nested switch/case statements to apply the correct values to the cells in their respective section/row. As far as i can tell the logic in these statements is correct, so is it possible that the value of cell variable is inccorect when updating?
The table loads correctly but after scrolling accessoryType and detailedTextLabel gets mixed up.
Click for link to screen shots of the table.
Here is the code inside of my UITableViewController subclass:
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return [sectionNames count];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
// Return the number of rows in the section.
NSArray *headingsSection = [cellTitles objectAtIndex:section];
return [headingsSection count];
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
return [sectionNames objectAtIndex:section];
}
// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
self.tableView.allowsSelection = YES;
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifier] autorelease];
}
cell.textLabel.text = [[cellTitles objectAtIndex:indexPath.section] objectAtIndex:indexPath.row];
cell.textLabel.textColor = [UIColor blackColor];
cell.textLabel.font = [UIFont boldSystemFontOfSize:15];
switch (indexPath.section) {
case 0:
cell.detailTextLabel.text = [NSString stringWithFormat:#"%d%%", [[assistSettingsArray_glob objectAtIndex:indexPath.row] intValue]];
break;
case 1:
switch (indexPath.row) {
case 0:
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
break;
case 1:
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
break;
case 2:
if (defaultAssistOn) {
cell.accessoryType = UITableViewCellAccessoryCheckmark;
} else {
cell.accessoryType = UITableViewCellAccessoryNone;
}
break;
}
break;
}
return cell;
}
Due to cell re-use, cells with previously set values re-appear.
Before the switch (indexPath.section) ..., initialize the detailTextLabel and accessoryType to defaults:
cell.detailTextLabel.text = #"";
cell.accessoryType = UITableViewCellAccessoryNone;
Try to enclose the code in each switch cases inside parantheisis. So the above code looks like this:
switch (indexPath.section) {
case 0: {
cell.detailTextLabel.text = [NSString stringWithFormat:#"%d%%",
[[assistSettingsArray_glob objectAtIndex:indexPath.row] intValue]];
break;
}
case 1: {
switch (indexPath.row) {
case 0: {
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
break; }
case 1: {
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
break; }
case 2: {
if (defaultAssistOn) {
cell.accessoryType = UITableViewCellAccessoryCheckmark;
}
else{
cell.accessoryType = UITableViewCellAccessoryNone;
}
break; }
default:
break;
}
break;
}
default:
break;
}
I am not sure whether this work. Do inform if it does :)