Reputation: 2057
I have a tableview with a lot of entries divided into multiple sections and inside that I have multiple rows.I have a button modelled as a checkbox in each rows. The checkboxes(buttons) can be activated/deactivated when pressed. I am loading an image on the button(checkbox) based on the status, whether it is checked or not. Everything is going fine, until I try to drag my UITableview downwards and then go up, only to find some of my checked checkboxes automatically unchecked. I kind of figured that, this was caused due to the use of
dequeuereusablecellwithidentifier
I want to avoid this strange behavior of my tableview. Need help in this case.
- (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];
UIButton *checkBox = [[UIButton alloc] init];
checkBox.tag = contact.contactID;
[cell.contentView addSubview:checkBox];
[checkBox setFrame:CGRectMake(6,14,20,20)];
[checkBox release];
}
UIButton *checkBox = (UIButton *)[cell.contentView viewWithTag:contact.contactID];
if(isActivDeactivButton)
{
[checkBox setImage:[UIImage imageNamed:@"disabled_checkbox.png"] forState:UIControlStateNormal];
}
else{
[checkBox setImage:[UIImage imageNamed:@"selected_checkbox.png"] forState:UIControlStateNormal];
}
return cell;
}
Upvotes: 0
Views: 2452
Reputation: 2057
I replaced
checkBox.tag = contact.contactID;
with
checkBox.tag = 111;
This solved the problem as my contactID values were changing during scroll.
Upvotes: 0
Reputation: 655
// Add following methods def in viewController .h
-(void)checkButtonPressed:(id)sender;
-(void)addSelectedCheckBoxTag:(int)value;
-(void)deleteSelectedCheckBoxTag:(int)value;
-(BOOL)isSelectedCheckBox:(int)value;
// add target to the check button in cellForRowAtIndexPath -
[checkBox addTarget:self action:@selector(checkButtonPressed:) forControlEvents:UIControlStateNormal];
// Ad following methods in viewController .m where tabelView
-(void)checkButtonPressed:(id)sender
{
UIButton *checkBox=(UIButton*)sender;
if(checkBox.selected)
{
checkBox.selected=false;
[checkBox setImage:[UIImage imageNamed:@"disabled_checkbox.png"] forState:UIControlStateNormal];
[self deleteSelectedCheckBoxTag:checkBox.tag];
NSLog(@"unselected ..");
}
else
{
checkBox.selected=true;
[self addSelectedCheckBoxTag:checkBox.tag];
[checkBox setImage:[UIImage imageNamed:@"selected_checkbox.png"] forState:UIControlStateNormal];
NSLog(@"selected..");
}
}
// Add element in to array if already present forget
-(void)addSelectedCheckBoxTag:(int)value
{
int flag=0;
for(int i=0;i<[arrayForTag count];i++)
{
if([[arrayForTag objectAtIndex:i] intValue]==value)
flag=1;
}
if(flag==0)
[arrayForTag addObject:[NSString stringWithFormat:@"%d",value]];
}
// delete element add in array if present
-(void)deleteSelectedCheckBoxTag:(int)value
{
for(int i=0;i<[arrayForTag count];i++)
{
if([[arrayForTag objectAtIndex:i] intValue]==value)
[arrayForTag removeObjectAtIndex:i];
}
}
// For take is selected or not from array -
-(BOOL)isSelectedCheckBox:(int)value
{
for(int i=0;i<[arrayForTag count];i++)
{
if([[arrayForTag objectAtIndex:i] intValue]==value)
return true;
}
return false;
}
// In cellForRowAtIndexPath replace following code
if(isActivDeactivButton)
{
[checkBox setImage:[UIImage imageNamed:@"disabled_checkbox.png"] forState:UIControlStateNormal];
}
else{
[checkBox setImage:[UIImage imageNamed:@"selected_checkbox.png"] forState:UIControlStateNormal];
}
// with following code -
if(![self isSelectedCheckBox:checkBox.tag])
{
[checkBox setImage:[UIImage imageNamed:@"disabled_checkbox.png"] forState:UIControlStateNormal];
}
else{
[checkBox setImage:[UIImage imageNamed:@"selected_checkbox.png"] forState:UIControlStateNormal];
}
Upvotes: 2
Reputation: 14446
Make sure your logic for -tableView:cellForRowAtIndexPath:
is set up as follows:
// 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) {
// this part is called when the cell is created anew
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
// add new components here (this is where you'd add your checkbox control, etc)
}
// change the state of components here (this is where you'd make sure your checked property is set correctly
return cell;
}
Using dequeueReusableCellWithIdentifier:
is great practice for memory management, so you want to keep this for sure.
Upvotes: 2