hanumanDev
hanumanDev

Reputation: 6614

Multiple accessory checkmarks displayed on a UITableView

I have a UITableView that displays checkmarks when a row is selected. The problem is that when the table view scrolls multiple checkmarks are shown when only one was ever row selected. The problem arises as the table scrolls and the dequeue process occurs. Here's my cellForRowAtIndexPath: method

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"MainCell"];

    if(cell == nil){
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"MainCell"];

        cell.selectedBackgroundView = [[UIView alloc] initWithFrame:CGRectZero];

        cell.selectedBackgroundView.backgroundColor = [UIColor colorWithRed:204.0/255.0 green:56.0/255.0 blue:55.0/255.0 alpha:1];

    }

    // Get item from tableData
    NSDictionary *item = (NSDictionary *)[displayItems objectAtIndex:indexPath.row];

    cell.textLabel.text = [item objectForKey:@"key"];

    [cell.textLabel setFont:[UIFont fontWithName: @"Asap-Bold" size: 14.0f]];

    return cell;
}

and didSelect method:

-(void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    [tableView deselectRowAtIndexPath:indexPath animated:YES];

    UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
    selectedCityTableString = cell.textLabel.text;

    cellAccessoryImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"icon-tick.png"]] ;
    cellAccessoryNoneImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@""]] ;

    if (cell.accessoryType==UITableViewCellAccessoryNone)
    {
        //        cell.accessoryType=UITableViewCellAccessoryCheckmark;

        cell.accessoryView = cellAccessoryImageView;

        if (prev!=indexPath.row) {
            cell=[tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:prev inSection:0]];
            //cell.accessoryType=UITableViewCellAccessoryNone;
            cell.accessoryView = cellAccessoryNoneImageView;

            prev=indexPath.row;
        }
    }
    else{
        //        cell.accessoryType=UITableViewCellAccessoryNone;
        cell.accessoryView = cellAccessoryNoneImageView;

    }

    NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];

    NSString *mutCityStr = [[selectedCityTableString stringByReplacingOccurrencesOfString:@" " withString:@"+"] lowercaseString];

   // NSString *mutCityStr = @"c";

    [prefs setObject:mutCityStr forKey:@"selectedCityTableString"];
    [prefs synchronize];

#ifdef DEBUG    
    NSLog(@"mutCityStr is %@",mutCityStr);
    NSLog(@"selectedCityTableString is %@",selectedCityTableString);
    NSLog(@"posting notification from TWO TABLES");
#endif

    [[NSNotificationCenter defaultCenter] postNotificationName:@"TTSelectedList" object:selectedCountryTableString];

}

Upvotes: 0

Views: 2744

Answers (4)

Vishnu
Vishnu

Reputation: 2243

In your .h file

int selectedRow;

In your .m file

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{
        // your other code for cell init,etc
        int row = [indexPath row];
        cell.accessoryType = (row == selectedRow) ? UITableViewCellAccessoryCheckmark : UITableViewCellAccessoryNone;

        cell.textLabel.textColor= (row == selectedRow) ? [UIColor colorWithRed:242.0f/255.0f green:104.0f/255.0f blue:42.0f/255.0f alpha:1] : [UIColor blackColor] ;

}

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

    selectedRow = [indexPath row];
    [tableView reloadData];
}

Hope this helps!!!

Upvotes: 2

tkanzakic
tkanzakic

Reputation: 5499

Supposing you have a property (attribute) called selectedRow use the combination of this methods:

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

    if (indexPath.row == self.selectedRow) {
        cell.accessoryType = UITableViewCellAccessoryCheckmark;
    } else {
        cell.accessoryType = UITableViewCellAccessoryNone;
    }

    return cell;
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    // If there is a cell selected deselect
    if (self.selectedRow != NSNotFound) {
        NSIndexPath *previousIndexPath = [NSIndexPath indexPathForRow:self.selectedAQIType inSection:0];
        UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:previousIndexPath];
        cell.accessoryType = UITableViewCellAccessoryNone;
    }

    // Select the touched cell
    UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];
    cell.accessoryType = UITableViewCellAccessoryCheckmark;
    self.selectedRow = indexPath.row;
}

Upvotes: 3

Mrunal
Mrunal

Reputation: 14118

To solve this problem, store your selected row indexes in one NSArray. (in didSelectRowAtIndexPath method)

And in cellForRowAtIndexPath method, check whether indexPath.row is available in that array then enable your checkmark, else disable.

Note: Maintain array for check-uncheck event

Hope this will help you.

Upvotes: 0

Praveen S
Praveen S

Reputation: 10393

UITableView's delegate method - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath reuses the cell based on the reuseidentifier. Hence you need to reset the entire cell contents to default.

In your case uncheck the cell's view before you return the cell.

Upvotes: 0

Related Questions