pengwang
pengwang

Reputation: 19956

UITableViewCell reuse good practice

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


    static NSString *CellIdentifier = @"NotificationViewCell";
    CardViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if(cell==nil){

        NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"CardViewCell" owner:self options:nil];
        cell = [nib objectAtIndex:0];


        cell.contentView.backgroundColor=[UIColor clearColor];
        [ModelClass addSublayer:cell.contentView];


        cell.cellbg.layer.cornerRadius = 8;
        cell.cellbg.layer.masksToBounds = YES;

         cell.cellbg.layer.borderWidth = 1;
         cell.cellbg.layer.borderColor = [[UIColor grayColor] CGColor];


        cell.logoImage.layer.cornerRadius = 8;
        cell.logoImage.layer.masksToBounds = YES;

        cell.logoImage.layer.borderWidth = 1;
        cell.logoImage.layer.borderColor = [[UIColor grayColor] CGColor];



        Merchant *merchantList= [self.cardListArr objectAtIndex:indexPath.row];

        cell.nameLab.text=merchantList.name;

        NSLog(@"merchantList.myloyalty.points=%@",merchantList.myloyalty.points);
    //    NSLog(@"memberNO=%@",merchantList.myloyalty.memberNO);
        cell.integralLab.text=[NSString stringWithFormat:NSLocalizedString(@"points_dot", @"") ,[merchantList.myloyalty.points intValue]];


        cell.cardNumberLab.text=[NSString stringWithFormat:@"%@%@",NSLocalizedString(@"ID", nil), merchantList.myloyalty.memberNO];



        if(![ModelClass isBlankString:merchantList.introPic])
        {
              NSLog(@"merchantList.introPic=%@",merchantList.introPic);

            [cell.logoImage setImageUrl:merchantList.introPic];


        }
    }

    return cell;

}
  1. i want to use the above code to reuse UITableViewCell,i donot know if it is correct,i want to get some advice.
  2. you can see my code i use if(cell==nil),i want to know i should write what code if(cell!=nil)(if(cell==nil) else{ i should do what can improve the cell reuse})

  3. if every cell have have same views,but have different height,for example imageview sometimes is 20 or is 40 and so on ,how to deal with the situation.

Upvotes: 4

Views: 11974

Answers (3)

GyroCocoa
GyroCocoa

Reputation: 1612

The above answer by Guo Luchuan works fine but the problem is it recreates cells every time you scroll up and down and if you have UIComponents that have different states you may easily lose those states. In addition I recommend that you cache all created cells and reuse them to avoid that situation.

Here's an example of how the cache would work.

var mockCells = [QuestionsCell](repeating: QuestionsCell(), count: 1000)

*Inside your cellForRowAtIndexPath put the following *

 if cell == indexPath.row {
            //if cell exists in our list we reuse
            cell = mockCell
        } else {
            //here we store/cache each created cell 
                mockCells[indexPath.row] = cell
            }
        }

Upvotes: 0

Guo Luchuan
Guo Luchuan

Reputation: 4731

1.It is not correct , because your cell is reused , and when it is created , it will not to go into the if-statement , so , in the if-statement you only need to do is to init the cell , the setText and setImage you should code outside the if-statement .

such as :

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


    static NSString *CellIdentifier = @"NotificationViewCell";
    CardViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if(cell==nil){

        NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"CardViewCell" owner:self options:nil];
        cell = [nib objectAtIndex:0];


        cell.contentView.backgroundColor=[UIColor clearColor];
        [ModelClass addSublayer:cell.contentView];


        cell.cellbg.layer.cornerRadius = 8;
        cell.cellbg.layer.masksToBounds = YES;

         cell.cellbg.layer.borderWidth = 1;
         cell.cellbg.layer.borderColor = [[UIColor grayColor] CGColor];


        cell.logoImage.layer.cornerRadius = 8;
        cell.logoImage.layer.masksToBounds = YES;

        cell.logoImage.layer.borderWidth = 1;
        cell.logoImage.layer.borderColor = [[UIColor grayColor] CGColor];

        }

        Merchant *merchantList= [self.cardListArr objectAtIndex:indexPath.row];

        cell.nameLab.text=merchantList.name;

        NSLog(@"merchantList.myloyalty.points=%@",merchantList.myloyalty.points);
    //    NSLog(@"memberNO=%@",merchantList.myloyalty.memberNO);
        cell.integralLab.text=[NSString stringWithFormat:NSLocalizedString(@"points_dot", @"") ,[merchantList.myloyalty.points intValue]];


        cell.cardNumberLab.text=[NSString stringWithFormat:@"%@%@",NSLocalizedString(@"ID", nil), merchantList.myloyalty.memberNO];



        if(![ModelClass isBlankString:merchantList.introPic])
        {
              NSLog(@"merchantList.introPic=%@",merchantList.introPic);

            [cell.logoImage setImageUrl:merchantList.introPic];


        }


        return cell;

    }

2 Most people code like this :

if(cell==nil)
{
    //init code
}

// setting code

3.If you want set the cell height , you can not code in the - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath

you should code in the method of dataSource : - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath

code like this :

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    if (index.row % 2)
        return 20.0f;
    return 40.0f;
}

Upvotes: 6

MrTJ
MrTJ

Reputation: 13192

I usually separate the creation and configuration of the cell into two logical parts:

  1. Create the cell and set up all its properties that are the same for every single cell (i.e. layout, layer)
  2. Write a separate -(void)configureCell:(UITableViewCell*)cell; function where I set up everything specific for a particular cell from the datasource (i.e. values of labels and imageView).

Then in cellForRowAtIndexPath:

-(UITableViewCell *)tableView:(UITableView *)tableView 
        cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{
    static NSString *CellIdentifier = @"NotificationViewCell";
    CardViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if(cell==nil){
       [self createCell:&cell];
    }

    Mercant* mercantList = [self.cardListArr objectAtIndex:indexPath.row];

    [self configureCell:cell withMercant:mercantList];

    return cell;
}

-(void)createCell:(CardViewCell**)cellPtr
{
    NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"CardViewCell" 
                                                 owner:self 
                                               options:nil];
    *cellPtr = [nib objectAtIndex:0];

    CardViewCell* cell = *cellPtr;

    cell.contentView.backgroundColor=[UIColor clearColor];
    [ModelClass addSublayer:cell.contentView];

    cell.cellbg.layer.cornerRadius = 8;
    cell.cellbg.layer.masksToBounds = YES;

    cell.cellbg.layer.borderWidth = 1;
    cell.cellbg.layer.borderColor = [[UIColor grayColor] CGColor];


    cell.logoImage.layer.cornerRadius = 8;
    cell.logoImage.layer.masksToBounds = YES;

    cell.logoImage.layer.borderWidth = 1;
    cell.logoImage.layer.borderColor = [[UIColor grayColor] CGColor];
}

-(void)configureCell:(CardViewCell*)cell withMercant:(Mercant*)mercantList
{
    cell.nameLab.text=merchantList.name;

    NSLog(@"merchantList.myloyalty.points=%@",merchantList.myloyalty.points);
//    NSLog(@"memberNO=%@",merchantList.myloyalty.memberNO);
    cell.integralLab.text=[NSString stringWithFormat:NSLocalizedString(@"points_dot", @"") ,[merchantList.myloyalty.points intValue]];


    cell.cardNumberLab.text=[NSString stringWithFormat:@"%@%@",NSLocalizedString(@"ID", nil), merchantList.myloyalty.memberNO];



    if(![ModelClass isBlankString:merchantList.introPic])
    {
          NSLog(@"merchantList.introPic=%@",merchantList.introPic);

        [cell.logoImage setImageUrl:merchantList.introPic];


    }
}

Upvotes: 1

Related Questions