user1978374
user1978374

Reputation: 15

Checkboxes in UITableviewcell disappear as table scrolls

I am attempting to create a checkbox in each uitableviewcell that can toggle between selected and unselected. To make sure that a single selection doesn't recycle when loading new cells, I created a mutable array of strings to signify "Uncheck" or "Check" (i.e. when the button image should appear unchecked or checked). When the check button is pressed, the string is replaced by "Check" or "Uncheck". For some reason that I cannot see, when the tableview scrolls and the cell with the selected check button goes offscreen, the array loses the change made to it, and, thus, the check string is lost.

Any ideas what's wrong?

Thanks in advance for the help.

An NSLog of selectedCheckArray right after button in 1st cell is checked in "checkButtonClicked": { Check, Uncheck, Uncheck, Uncheck, Uncheck, Uncheck, Uncheck }

An NSLog of selectedCheckArray after I scroll down so that 1st cell is no longer on screen: { Uncheck, Uncheck, Uncheck, Uncheck, Uncheck, Uncheck, Uncheck }

Here's the code:

.h

    @property (strong, nonatomic) NSMutableArray *selectedCheckArray;

.m

    @synthesize selectedCheckArray;

...

    - (void)viewWillAppear:(BOOL)animated
    {
        // cellDataArray loaded here

        selectedCheckArray = [[NSMutableArray alloc] init];

        for (int i = 0; i<[cellDataArray count]; i++) {
            [selectedCheckArray addObject:@"Uncheck"];
        } 

        [super viewWillAppear:animated];
    } 


    - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
    {
        return [cellDataArray count];
    }

    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
    {
         static NSString *CellIdentifier = @"choiceCell";

        UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
        if (cell == nil) {
            cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
        }

        UIButton *checkButton = (UIButton *)[cell viewWithTag:1];

        if ([[selectedCheckArray objectAtIndex:indexPath.row] isEqualToString:@"Uncheck"])         {
            [checkButton setImage:[UIImage imageNamed:@"unchecked"]   
               forState:UIControlStateNormal];
        } else {
            [checkButton setImage:[UIImage imageNamed:@"checked"] 
               forState:UIControlStateNormal];
        }
        [checkButton addTarget:self action:@selector(checkButtonClicked:)  
           forControlEvents:UIControlEventTouchUpInside];

        return cell;
    }

...

    - (void)checkButtonClicked:(id)sender
    {
        // indexPath of cell of clicked button
        CGPoint touchPoint = [sender convertPoint:CGPointZero toView:choiceTable];
        NSIndexPath *indexPath = [choiceTable indexPathForRowAtPoint:touchPoint];

        // Not using tag as sender will keep reference of clicked button
        UIButton *button = (UIButton *)sender;

        //Checking the condition button is checked or unchecked.
        //accordingly replace the array object and change the button image
        if([[selectedCheckArray objectAtIndex:indexPath.row] isEqualToString:@"Uncheck"])
        {
            [button setImage:[UIImage imageNamed:@"checked"] forState:UIControlStateNormal];
            [selectedCheckArray replaceObjectAtIndex:indexPath.row withObject:@"Check"];
        } else {
            [button setImage:[UIImage imageNamed:@"unchecked"] forState:UIControlStateNormal];
            [selectedCheckArray replaceObjectAtIndex:indexPath.row withObject:@"Uncheck"];
        }
    }

Upvotes: 0

Views: 2294

Answers (1)

Manann Sseth
Manann Sseth

Reputation: 2745

Try this,

in .h file,

NSMutableArray *arrayCellChecked;

@property(nonatomic, retain) NSIndexPath *lastIndexPath;

in .m file

@synthesize lastIndexPath;
int oldRow, newRow;

In DidLoad Method,

arrayCellChecked = [[NSMutableArray alloc] init];

Table Row Method,

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

        //Your Code
        ----------

        newRow = [indexPath row];
        oldRow = [[self lastIndexPath] row];


        cell.accessibilityViewIsModal = (newRow == oldRow && lastIndexPath != nil) ? NO : YES;

        if(cell.accessibilityViewIsModal == YES)
            [checkButton setImage:[UIImage imageNamed:@"unchecked"] forState:UIControlStateNormal];
        else
            [checkButton setImage:[UIImage imageNamed:@"checked"] forState:UIControlStateNormal];

        //Your Method for Button Click
        -----------

        return cell;
}

Table Cell Selection Method,

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {

    //Your Cell Code
    -------

    if (cell.accessibilityViewIsModal == NO) {

        cell.imgCheck.image = [UIImage imageNamed:@"checked"];
        cell.accessibilityViewIsModal = YES;

        NSString *cellValue = yourArray.object;

        [arrayCellChecked addObject:cellValue];

        -------
    }

    else{

        cell.imgCheck.image = [UIImage imageNamed:@"unchecked"];
        cell.accessibilityViewIsModal = NO;

        NSString *cellValue = yourArray.object;

        [arrayCellChecked removeObject:cellValue];

        --------
    }
 }

It'll done for 'didSelectRowAtIndex'.. No need of button click method.

I've resolved it with this way.

Hopefully It'll work for you. Thanks.

Upvotes: 1

Related Questions