Lapinou
Lapinou

Reputation: 1477

UITableViewCell with checkbox repeating while scrolling

I'm using a UITableView witha custom cell (xib). Each cell are lables and a checkbox (UIButton).

I have 2 sections and 4 cells in each section. If I check the first cell of the first section, the forst cell of the second section will be check as well and I don't want. The problem: dequeueReusableCellWithIdentifier:CellIdentifier.

I want to hold my cell identifier static.

How can I fix this ?

Here is the initializing of my array (for the content of my cells):

for(int i=0; i<NUMBER_OF_CELL; i++){

    Account *model = [[Account alloc]init];

    [model setAccountName:[NSString stringWithFormat:@"Account %d",i]];
    [model setAccountNumber:[NSString stringWithFormat:@"Number %d",i]];

    [_accountArray addObject:model];

}

Setting the content:

[[cell accountLabel] setText:_model.accountName];
[[cell accountNumberLabel] setText:_model.accountNumber];

EDIT:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"Cell";
    _model = [_accountArray objectAtIndex:indexPath.row];

    AccountCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:@"AccountCell" owner:self options:nil];
        cell = [topLevelObjects objectAtIndex:0];
    }
    // configure cell 
    [cell setSelectionStyle:UITableViewCellSelectionStyleNone];

    [[cell accountLabel] setText:_model.accountName];
    [[cell accountNumberLabel] setText:_model.accountNumber];
    // checkbox ? 

    if(cell.isChecked){

        NSLog(@"Checked");
    }else{
        NSLog(@"No checked");
    }

    return cell;
}

In an other class, I check if the checkbox is checked or not:

- (IBAction)checkbox:(id)sender {

    NSIndexPath *indexPath = [(UITableView *)self.superview indexPathForCell: self];

    if(self.isChecked == NO)
    {
        self.isChecked = YES;
        [_checkbox setImage:[UIImage imageNamed:@"checkbox_checked.png"] forState:UIControlStateNormal];        
    }
    else{
        self.isChecked = NO;
        [_checkbox setImage:[UIImage imageNamed:@"checkbox.png"] forState:UIControlStateNormal];
    }

}

How can I distinguish each cell to avoid repeating checking ?

Thank you so much! Best regards,

Upvotes: 0

Views: 1326

Answers (2)

cdemiris99
cdemiris99

Reputation: 607

I think you'd be best using the selected state for the button to track whether it is checked. It looks like you've created an "AccountCell" class, so you should be able to simply have an outlet for the checkbox in the AccountCell class, such as:

@interface AccountCell : UITableViewCell
...
@property IBOutlet UIButton *checkBox;

Now, you can set the normal/checked images for the button in the AccountCell's viewDidLoad method (since this doesn't need to be done every time state changes):

- (void)viewDidLoad
{
    [super viewDidLoad];
    [_checkBox setImage:[UIImage imageNamed:"checkbox.png" forState:UIControlStateNormal];
    [_checkBox setImage:[UIImage imageNamed:"checkbox_checked.png" forState:UIControlStateSelected];
}

In your cellForRowAtIndex path you can make sure the checkbox is cleared for the returned cell by using:

cell.checkBox.selected = NO;

Then in the 'action' code for the checkbox you can use the following to switch the checkbox on and off:

self.selected = !self.selected;

Upvotes: 0

Kunal
Kunal

Reputation: 649

You need to write following method in AccountCell.h/AccountCell.m

- (void)resetCell {

    //Reset Your cell content to default. So that you can reuse the cell.
    NSIndexPath *indexPath = [(UITableView *)self.superview indexPathForCell: self];


        self.isChecked = NO;
        [_checkbox setImage:[UIImage imageNamed:@"checkbox.png"] forState:UIControlStateNormal];

    //other resettings...
}

And then you can call this method from (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath as follows

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"Cell";
    _model = [_accountArray objectAtIndex:indexPath.row];

    AccountCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];


    if (cell == nil) {
        NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:@"AccountCell" owner:self options:nil];
        cell = [topLevelObjects objectAtIndex:0];
    }
    // configure cell 
    [cell setSelectionStyle:UITableViewCellSelectionStyleNone];

    //reset your cell's content.
    [cell resetCell];

    //perform your task below
    [[cell accountLabel] setText:_model.accountName];
    [[cell accountNumberLabel] setText:_model.accountNumber];
    // checkbox ? 

    if(cell.isChecked){

        NSLog(@"Checked");
    }else{
        NSLog(@"No checked");
    }

    return cell;
}

Hope this helps.

Thanks.

Upvotes: 1

Related Questions