简体   繁体   中英

Single UITableViewCell with AccessoryView

I'm trying to build an UITableView with some long texts inside each cell. Cells are without AccessoryView, except for one cell (the 8th one), that is a sort of button to open a detail view.

Consider this code:

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    CGSize size = [[quotes objectAtIndex:indexPath.row] sizeWithFont:16 constrainedToSize:CGSizeMake(self.view.frame.size.width, CGFLOAT_MAX)];
    return size.height+20;
}

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

    static NSString *CellIdentifier = @"Cell";

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

    cell.textLabel.lineBreakMode = UILineBreakModeWordWrap;
    cell.textLabel.numberOfLines = 0;
    cell.textLabel.text = [quotes objectAtIndex:indexPath.row];

    if(indexPath.row==7){
        [cell setAccessoryType:UITableViewCellAccessoryDetailDisclosureButton];
    }

    return cell;
}

It works, but the problem is that when I scroll to the bottom of the Table (the 8th is also the last row) and then I go back to the upper side, another AccessoryView is added to a random point (more or less the 3rd cell, but I don't know if it is inside of it or is floating around randomly). Is it something related to cell reusing by iOS? How can I avoid it?

Thanks in advance.

The cell is being reused (as demonstrated by your call to -dequeueReusableCellWithIdentifer ).

The answer is to set the cell to wanted defaults after it's been dequeued, or add an else clause to the if statement to handle it.

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

    static NSString *CellIdentifier = @"Cell";

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

    cell.textLabel.lineBreakMode = UILineBreakModeWordWrap;
    cell.textLabel.numberOfLines = 0;
    cell.textLabel.text = [quotes objectAtIndex:indexPath.row];
    // Set to expected default
    [cell setAccessoryType:UITableViewCellAccessoryNone];

    if(indexPath.row==7){
        [cell setAccessoryType:UITableViewCellAccessoryDetailDisclosureButton];
    }

    return cell;
}

You have to explicitly set no disclosure button to every cell but the one that you wish to have disclosure. This way when the cell gets reused elsewhere its disclosure indicator is removed:

 if(indexPath.row==7){
        [cell setAccessoryType:UITableViewCellAccessoryDetailDisclosureButton];
    }else{
        [cell setAccessoryType:UITableViewCellAccessoryNone];
    }

This is due to cell reuse as you surmise. You must explicitly set UITableViewCellAccessoryNone for cells at index paths other than 7.

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