Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UITableView cell accessoryView image issue

I am trying to display a 'padlock' icon on specific rows of my UITableViewCells using this code:

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

    GPBTopic *topic = [self.topics.list objectAtIndex:indexPath.row];
    cell.textLabel.text= topic.name;

    if ((indexPath.row == 5) || (indexPath.row == 9))
    {
            cell.accessoryView = [[ UIImageView alloc ] initWithImage:[UIImage imageNamed:@"lock_icon.png"]];;
            [cell.accessoryView setFrame:CGRectMake(0, 0, 24, 24)];

    }

    return cell;
}

I am getting a funny result - the padlock is initially shown on rows 5,9 but when I scroll down and up the list the icon gets redisplayed by random on other cells' accessoryView as well (there's only 1 section btw), and the scrolling becomes quite jerky and laggy... The more I scroll up/down the more instances of it are displayed! Why? where's the bug here?

help, thanks!

like image 923
mindbomb Avatar asked Mar 11 '13 22:03

mindbomb


2 Answers

The cells get reused. You need to reset the accessoryView each time. Its just a small change:

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

    GPBTopic *topic = [self.topics.list objectAtIndex:indexPath.row];
    cell.textLabel.text= topic.name;

    if ((indexPath.row == 5) || (indexPath.row == 9))
    {
      cell.accessoryView = [[ UIImageView alloc ] initWithImage:[UIImage imageNamed:@"lock_icon.png"]];
      [cell.accessoryView setFrame:CGRectMake(0, 0, 24, 24)];
    } else {
      cell.accessoryView = nil; 
    }

    return cell;
}

Just for completion, you can also use Eric's solution like this - it may be faster, since the imageView is not created every time. But thats only a minimal difference. Probably your lags have other reasons.

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell *cell = nil;
    if(indexPath.row == 5 || indexPath.row == 9) {
        cell = [tableView dequeueReusableCellWithIdentifier:@"TopicCellWithImage"];
        cell.accessoryView = [[ UIImageView alloc ] initWithImage:[UIImage imageNamed:@"lock_icon.png"]];;
        [cell.accessoryView setFrame:CGRectMake(0, 0, 24, 24)];
    } else {
        cell = [tableView dequeueReusableCellWithIdentifier:@"TopicCell"];
    }

    GPBTopic *topic = [self.topics.list objectAtIndex:indexPath.row];
    cell.textLabel.text= topic.name;

    return cell;
}
like image 88
calimarkus Avatar answered Oct 24 '22 00:10

calimarkus


To showing custom accessoryView cell in Swift 4 & Swift 5

let lockIcon = UIImage(named: "lock_icon")
let lockIconView = UIImageView(image: lockIcon)
lockIconView.frame = CGRect(x: 0, y: 0, width: 24, height: 24)
cell.accessoryView = lockIconView
like image 39
Pengguna Avatar answered Oct 23 '22 22:10

Pengguna