UITableViewCell重用良好的做法

时间:2013-02-27 07:26:37

标签: iphone ios uitableview

- (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. 我想使用上面的代码重用UITableViewCell,我不知道它是否正确,我想得到一些建议。
  2. 你可以看到我使用的代码if(cell == nil),我想知道我应该编写代码if(cell!= nil)(if(cell == nil)else {i should do什么可以改善细胞再利用})

  3. 如果每个单元格具有相同的视图,但具有不同的高度,例如imageview有时为20或40,依此类推,如何处理这种情况。

3 个答案:

答案 0 :(得分:6)

1.这是不正确的,因为你的单元格被重用,当它被创建时,它不会进入if-statement,因此,在if-statement你只需要做的就是要初始化单元格,你应该在if-statement之外编码setText和setImage。

如:

- (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大多数人的代码如下:

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

// setting code

3.如果您想设置单元格高度,则无法在- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath

中进行编码

您应该使用dataSource的方法进行编码:- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath

像这样的代码:

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

答案 1 :(得分:1)

我通常将单元格的创建和配置分为两个逻辑部分:

  1. 创建单元格并设置每个单元格相同的所有属性(即布局,图层)
  2. 编写一个单独的-(void)configureCell:(UITableViewCell*)cell;函数,我从数据源设置特定单元格的所有内容(即标签和imageView的值)。
  3. 然后在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];
    
    
        }
    }
    

答案 2 :(得分:0)

郭禄川的上述答案运行良好,但问题是每次上下滚动时都会重新创建单元格,如果你有不同状态的UIComponents,你可能很容易丢失这些状态。此外,我建议您缓存所有已创建的单元格并重复使用它们以避免这种情况。

以下是缓存如何工作的示例。

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

*在你的cellForRowAtIndexPath中放入以下*

 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
            }
        }