简体   繁体   中英

How to display a custom UITableViewCellAccessoryCheckmark

I have a table view that needs a custom UITableViewCellAccessoryCheckmark. The checkmark displays when a row is selected and disappears when anther row is selected and then appears on the last most selected view. That works fine.

the problem arises when I use this line:

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

to add a custom UITableViewCellAccessoryCheckmark. After that code the UITableViewCellAccessoryCheckmark remain on all rows and don't disappear when another row is touched.

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

int index = indexPath.row; id obj = [listOfItems objectAtIndex:index];

   UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];

NSLog(@"%d",indexPath.row);
if (rowNO!=indexPath.row) {
    rowNO=indexPath.row;
    [self.tableView cellForRowAtIndexPath:indexPath].accessoryType=UITableViewCellAccessoryCheckmark;

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

    [self.tableView cellForRowAtIndexPath:lastIndexPth].accessoryType=UITableViewCellAccessoryNone;
    lastIndexPth=indexPath;
}

A much cleaner and cooler way would be to overwrite UITableViewCell like this:

- (void)setAccessoryType:(UITableViewCellAccessoryType)accessoryType
{
    // Check for the checkmark
    if (accessoryType == UITableViewCellAccessoryCheckmark)
    {
        // Add the image
        self.accessoryView = [[[UIImageView alloc] initWithImage:[UIImage imageNamed:@"YourImage.png"]] autorelease];
    }
    // We don't have to modify the accessory
    else
    {
        [super setAccessoryType:accessoryType];
    }
}

If you have done that, you can continue using UITableViewCellAccessoryCheckmark because your class will automatically replace it with an image.

You should only set the style in your cellForRowAtIndexPath method. Like this:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    // [init subclassed cell here, dont forget to use the table view cache...]

    cell.accessoryType = (rowNO != indexPath.row ? nil : UITableViewCellAccessoryCheckmark);

    return cell;
}

And then, you just have to update rowNO in didSelectRowAtIndexPath to update your data and redraw the cell, like this:

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

    if (rowNO != indexPath.row)
    {
        rowNO = indexPath.row;
    }

    [self.tableView reloadData]; 

}

Also, instead of reloading the whole table with [self.tableView reloadData] , you could only reload the two cells that change their style (eg checkmark) using reloadRowsAtIndexPaths .

Hm don't know why but i can't add comments so im writing this as answer. The problem with Blauesocke answer is that the AccessoryType wil be not set to UITableViewCellAccessoryCheckmark so you can't check the cell AccessoryType. Is there some way to do it right so the cell AccessoryType will be corect type just another image.

I'm using the method like this :

- (void)setAccessoryType:(UITableViewCellAccessoryType)newAccessoryType
{
    [super setAccessoryType:newAccessoryType];
    // Check for the checkmark
    switch(newAccessoryType)
    {
        case UITableViewCellAccessoryCheckmark:
            self.accessoryView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"yorCheckmark.png"]];
            break;
        case UITableViewCellAccessoryNone:
            self.accessoryView = nil;
            break;
        default:
            break;
    }

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM