Checkmark is repeating when scrolling down the Tableview - iphone

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;
}

Related

Default Checklist in UITableView

I want to implement Checklist for a single selection in a UITableView. Also, I need a cell to be selected by default. Here's my implementation in cellForRowAtIndexPath:
NSUInteger row = [indexPath row];
NSUInteger oldRow = [lastIndexPath row];
cell.accessoryType = (row == oldRow && lastIndexPath != nil) ? UITableViewCellAccessoryCheckmark : UITableViewCellAccessoryNone;
if (indexPath.row == selectedRow ) {
cell.accessoryType = UITableViewCellAccessoryCheckmark;
}
else {
cell.accessoryType = UITableViewCellAccessoryNone;
}
didSelectRowAtIndexPath has this code:
if (!self.lastIndexPath) {
self.lastIndexPath = indexPath;
}
if ([self.lastIndexPath row] != [indexPath row])
{
UITableViewCell *newCell = [tableView cellForRowAtIndexPath: indexPath];
newCell.accessoryType = UITableViewCellAccessoryCheckmark;
UITableViewCell *oldCell = [tableView cellForRowAtIndexPath:self.lastIndexPath];
oldCell.accessoryType = UITableViewCellAccessoryNone;
self.lastIndexPath = indexPath;
}
else {
UITableViewCell *newCell = [tableView cellForRowAtIndexPath: indexPath];
newCell.accessoryType = UITableViewCellAccessoryCheckmark;
}
With this code I'm able to get a default checkmark, but whenever I select another row
the first one remains selected until I don't click that cell. So, If I want to select my desired result what should I do?
`
I think the code is a little too complicated. All you need is a single property:
NSInteger _selectedRow;
This, when initially defined, will provide a default selected row. And it will also maintain the previous selection (when looking for the cell to 'unselect'):
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CELL_IDENTIFIER];
if (!cell) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CELL_IDENTIFIER];
}
if ([indexPath row] == _selectedRow) {
cell.accessoryType = UITableViewCellAccessoryCheckmark;
}
cell.textLabel.text = [NSString stringWithFormat:#"Row %d", indexPath.row];
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
if (_selectedRow >= 0) {
[tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:_selectedRow inSection:0]].accessoryType = UITableViewCellAccessoryNone;
}
_selectedRow = [indexPath row];
[tableView cellForRowAtIndexPath:indexPath].accessoryType = UITableViewCellAccessoryCheckmark;
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}
When this view is created, if you assign:
_selectedRow = 1;
Then the second row will automatically be selected. A value of -1 indicates no default selection, and the two above methods will automatically add/remove the checkmarks from tapped rows.

Logic for UITableViewCellAccessoryCheckmark

I want to make a typical situation: when user selects any cell, it's accessoryType turns in checkmark. Only one cell's accessoryType can be checkmark. And then I wanna save in NSUserDefaults indexPath.row so my app will be able to know which cell user selected and make some changes in options. So I wrote this wrong code:
didSelectRowAtIndexPath
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
// checkedIndexPath is NSIndexPath
if(self.checkedIndexPath)
{
UITableViewCell* uncheckCell = [tableView
cellForRowAtIndexPath:self.checkedIndexPath];
uncheckCell.accessoryType = UITableViewCellAccessoryNone;
}
UITableViewCell* cell = [tableView cellForRowAtIndexPath:indexPath];
cell.accessoryType = UITableViewCellAccessoryCheckmark;
self.checkedIndexPath = indexPath;
[[NSUserDefaults standardUserDefaults]setObject:[NSNumber numberWithInt:self.checkedIndexPath.row]forKey:#"indexpathrow" ];
}
cellForRowAtIndexPath
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
// Part of code from cellForRowAtIndexPath
if(indexPath.row == [[[NSUserDefaults standardUserDefaults]objectForKey:#"indexpathrow"]intValue ])
{
cell.accessoryType = UITableViewCellAccessoryCheckmark;
}
else
{
cell.accessoryType = UITableViewCellAccessoryNone;
}
return cell;
}
However, this code works badly. When you open the UITableView, there is an already selected cell in the table and when you press another there are two checkmarked cells...How can I improve my code or should I change it whole ? Any suggestions ?
Thanks !
Try this code:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
// checkedIndexPath is NSIndexPath
NSIndexPath *previousSelection = self.checkedIndexPath;
NSArray *array = nil;
if (nil != previousSelection) {
array = [NSArray arrayWithObjects:previousSelection, indexPath, nil];
} else {
array = [NSArray arrayWithObject:indexPath];
}
self.checkedIndexPath = indexPath;
[tableView reloadRowsAtIndexPaths:array withRowAnimation: UITableViewRowAnimationNone];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
// Part of code from cellForRowAtIndexPath
NSString *cellID = #"CellID";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellID];
if (nil == cell) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellID];
[cell autorelease];
}
// some code for initializing cell content
cell.selectionStyle = UITableViewCellSelectionStyleNone;
if(self.checkedIndexPath != nil && indexPath.row == self.checkedIndexPath.row)
{
cell.accessoryType = UITableViewCellAccessoryCheckmark;
} else {
cell.accessoryType = UITableViewCellAccessoryNone;
}
return cell;
}

How to Select & checkmark the row after load in UITableview

I have a selection that will select just 1 row of category.
but I will like it to select Spirits row when loaded.
Something like this:
At the moment it comes to this without selecting anything:
Where shall I do the compare for the in order for it to selectRowAtIndexPath?
// 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:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
}
categoryString = [arrayCategory objectAtIndex:indexPath.row];
cell.textLabel.text = categoryString;
if (cell.textLabel.text == categoryString) {
cell.accessoryType = UITableViewCellAccessoryCheckmark;
}
else {
cell.accessoryType = UITableViewCellAccessoryNone;
}
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell* newCell = [tableView cellForRowAtIndexPath:indexPath];
int newRow = [indexPath row];
int oldRow = (lastIndexPath != nil) ? [lastIndexPath row] : -1;
if(newRow != oldRow)
{
newCell.accessoryType = UITableViewCellAccessoryCheckmark;
newCell.highlighted =YES;
UITableViewCell* oldCell = [tableView cellForRowAtIndexPath:lastIndexPath];
oldCell.accessoryType = UITableViewCellAccessoryNone;
lastIndexPath = indexPath;
oldCell.highlighted = NO;
}
[tableView deselectRowAtIndexPath:(NSIndexPath *)indexPath animated:YES];
}
Use selectRowAtIndexPath:animated:scrollPosition: method to select a row programatically.
Few things to correct in your code. You should use isEqualToString: method to match the strings, like this, if ([cell.textLabel.text isEqualToString:categoryString]) {. Next thing is, you are assigning the categoryString to cell.textLabel.text, and on the next line you are matching them, so it would always return YES. I think you are matching the wrong values.
You have to manually set multiple check marks. for that you can use UIImageview for each UITableViewCell and as per the stored old data, you have to set check marks in didSelectRowAtIndexPath(delegate method of UITableView).

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;
}

Checkmarks in a UITableView

I create a tableview with 20 cells.
And when I select first row, it will show checkmark on it.
But when I scroll tableview, then it not only one checkmark on tableview cell.
It also show on another cell.
What's the problem with this?
self.dataAry = [NSArray arrayWithObjects:#"0",#"1",#"2",#"3",#"4",#"5",#"6",#"7",#"8",#"9",#"10",#"11",#"12",#"13",#"14",#"15",#"16",#"17",#"18",#"19",nil];
marks = [NSMutableArray new];
for (int i = 0 ; i < [self.dataAry count]; i++) {
[marks addObject:#"NO"];
}
- (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];
}
cell.textLabel.text = [dataAry objectAtIndex:indexPath.row];
if ([[marks objectAtIndex:indexPath.row] isEqualToString:#"YES"]) {
[cell setAccessoryType:UITableViewCellAccessoryCheckmark];
}else {
[cell setAccessoryType:UITableViewCellAccessoryNone];
}
// Configure the cell.
return cell;}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
UITableViewCell *thisCell = [tableView cellForRowAtIndexPath:indexPath];
if ([[tableView cellForRowAtIndexPath:indexPath] accessoryType] == UITableViewCellAccessoryCheckmark){
[[tableView cellForRowAtIndexPath:indexPath] setAccessoryType:UITableViewCellAccessoryNone];
[selectArray removeObject:[self.dataAry objectAtIndex:indexPath.row]];
[marks replaceObjectAtIndex:indexPath.row withObject:#"NO"];
}
else {
[[tableView cellForRowAtIndexPath:indexPath] setAccessoryType:UITableViewCellAccessoryCheckmark];
[selectArray addObject:[self.dataAry objectAtIndex:indexPath.row]];
[marks replaceObjectAtIndex:indexPath.row withObject:#"YES"];
}
}
I think it is due to reusing the checkmarked cell. To correct that, write this:
*if ([[marks objectAtIndex:indexPath.row] isEqualToString:#"YES"]) {
[cell setAccessoryType:UITableViewCellAccessoryCheckmark];
}else {
[cell setAccessoryType:UITableViewCellAccessoryNone];*
Out of cell reusing space. That is After:
...
}
//Configure the cell.
just before
*return cell;*
Try this. Here selectedRow is an integer .Assign selectedRow = -1 in viewDidLoad.
- (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];
}
cell.selectionStyle = UITableViewCellSelectionStyleNone;
int row = [indexPath row];
cell.accessoryType = (row == selectedRow) ? UITableViewCellAccessoryCheckmark : UITableViewCellAccessoryNone;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
selectedRow = [indexPath row];
[tableView reloadData];
}
check this
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *thisCell = [tableView cellForRowAtIndexPath:indexPath];
if (thisCell.accessoryType == UITableViewCellAccessoryNone) {
thisCell.accessoryType = UITableViewCellAccessoryCheckmark;
}else{
thisCell.accessoryType = UITableViewCellAccessoryNone;
}
}
- (UITableViewCellAccessoryType)tableView:(UITableView *)tableView accessoryTypeForRowWithIndexPath:(NSIndexPath *)indexPath {
//add your own code to set the cell accesory type.
return UITableViewCellAccessoryNone;
}
i faced same issue. for me, solution was adding a single line of code.
cell.accessoryType = UITableViewCellAccessoryNone;
adding the above code after:
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
this solution may not be useful for coder who posted the question, but may help new folks like me who face same issue as raised by the original quesiton.