Default Checklist in UITableView - iphone

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.

Related

Checkmark is repeating when scrolling down the Tableview

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

deselect the previously selected cell in tableview

I have Table View with Multiple sections in it.
I want to allow only one row selected...My tableview's Selection Property is Set to:SingleSelectioin
Now I am doing this to set the checkmark for selected row
if([tableView cellForRowAtIndexPath:indexPath].accessoryType == UITableViewCellAccessoryCheckmark)
{
[tableView cellForRowAtIndexPath:indexPath].accessoryType = UITableViewCellAccessoryNone;
}
else
{
[tableView cellForRowAtIndexPath:indexPath].accessoryType = UITableViewCellAccessoryCheckmark;
}
Now what I want is that when I select any other cell, the previously selected cell should be set back to unselected.
I have tried with this
lastIndexpath=indexPath;
and then
[tableView deselectRowAtIndexPath:lastIndexpath animated:YES];
but it gives me bad access on lasIndexPath
EXC_BAD_ACCESS (code=1,address= 0xfe000008)
Kindly Help me with this
any New Suggestions are also welcomed
You want to mark your selected cell, then in didSelectRowAtIndexPath you can write code like this:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = (UITableViewCell*)[tableView cellForRowAtIndexPath:indexPath];
[cell setAccessoryType:UITableViewCellAccessoryCheckmark];
cell = (UITableViewCell*)[tableView cellForRowAtIndexPath:previousSelectedIndexPath];
[cell setAccessoryType: UITableViewCellAccessoryNone];
if(previousSelectedIndexPath!=nil)
{
[previousSelectedIndexPath release];
previousSelectedIndexPath = nil;
}
previousSelectedIndexPath = [indexPath retain];
}
where previousSelectedIndexPath is previously selected index;
Declare NSIndexPath *lastIndexpath in .h of your controller:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if( lastIndexpath){
if([tableView cellForRowAtIndexPath:lastIndexpath].accessoryType == UITableViewCellAccessoryCheckmark)
{
[tableView cellForRowAtIndexPath:lastIndexpath].accessoryType = UITableViewCellAccessoryNone;
}
else
{
[tableView cellForRowAtIndexPath:lastIndexpath].accessoryType = UITableViewCellAccessoryCheckmark;
}}
lastIndexpath=[indexPath retain]
if([tableView cellForRowAtIndexPath:indexPath].accessoryType == UITableViewCellAccessoryCheckmark)
{
[tableView cellForRowAtIndexPath:indexPath].accessoryType = UITableViewCellAccessoryNone;
}
else
{
[tableView cellForRowAtIndexPath:indexPath].accessoryType = UITableViewCellAccessoryCheckmark;
}
}
//Take a variable of type indexpath in .h
NSIndexPath *myIndexPath
//Now check it in your cellForRowAtIndexPath: delegate method ..
if(indexPath == myIndexPath)
cell.accessoryType = UITableViewCellAccessoryCheckmark;
else
cell.accessoryType = UITableViewCellAccessoryNone;
//and in your didSelect: Delegate method ...
[tableView cellForRowAtIndexPath:indexPath].accessoryType == UITableViewCellAccessoryCheckmark
myIndexPath = indexPath;
[tableView reloadData];
Hope this will help you.
in delegate method willSelectRowAtIndexPath , get the current selected index path, set accerroryType to none.
- (NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSIndexPath *currentSelectedIndexPath = [tableView indexPathForSelectedRow];
[tableView cellForRowAtIndexPath:currentSelectedIndexPath].accessoryType = UITableViewCellAccessoryNone;
if ([indexPath isEqualTo: currentSelectedIndexPath])
{
return nil;
}
return indexPath;
}

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).

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.

Accessory view in UITableView: view doesn't update

I'm trying to add checkmarks to items when the user select rows in a table view. However, the view is not refreshed and the checkmarks do no show up:
- (void)tableView:(UITableView *)tv didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell* oldCell = [self tableView:tv cellForRowAtIndexPath:[NSIndexPath indexPathForRow:selectedIndex inSection:0]];
oldCell.accessoryType = UITableViewCellAccessoryNone;
if (indexPath.section == 0) {
selectedIndex = indexPath.row;
}
UITableViewCell* newCell = [self tableView:tv cellForRowAtIndexPath:indexPath];
newCell.accessoryType = UITableViewCellAccessoryCheckmark;
[tv deselectRowAtIndexPath:indexPath animated:NO];
}
What could be a reason for that?
Call cellForRowAtIndexPath directly on the tv object instead of through self to make sure you get a proper cell reference back:
- (void)tableView:(UITableView *)tv didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *oldCell = [tv cellForRowAtIndexPath:[NSIndexPath indexPathForRow:selectedIndex inSection:0]];
oldCell.accessoryType = UITableViewCellAccessoryNone;
if (indexPath.section == 0) {
selectedIndex = indexPath.row;
}
UITableViewCell *newCell = [tv cellForRowAtIndexPath:indexPath];
newCell.accessoryType = UITableViewCellAccessoryCheckmark;
[tv deselectRowAtIndexPath:indexPath animated:NO];
}
Also make sure that in cellForRowAtIndexPath, you have this logic:
...
if (indexPath.row == selectedIndex)
cell.accessoryType = UITableViewCellAccessoryCheckmark;
else
cell.accessoryType = UITableViewCellAccessoryNone;
...
return cell;
otherwise, a checkmark will remain on a cell after it scrolls off the screen and comes back on screen even after you've selected another cell.