【问题标题】:UITableViewCell reuse good practiceUITableViewCell 复用的好习惯
【发布时间】:2017-10-06 01:58:33
【问题描述】:
- (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{ 我应该做什么什么可以提高细胞复用})

  3. 如果每个cell都有相同的view,但是高度不同,比如imageview有时候是20或者是40等等,如何处理。

【问题讨论】:

    标签: iphone ios uitableview


    【解决方案1】:

    1.不正确,因为你的cell是复用的,而且创建的时候不会进入if-statement,所以,在if-statement你只需要初始化cell , setText 和 setImage 你应该在 if-statement 之外编码。

    如:

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

    【讨论】:

    【解决方案2】:

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

    1. 创建单元格并设置其所有对每个单元格都相同的属性(即布局、图层)
    2. 编写一个单独的 -(void)configureCell:(UITableViewCell*)cell; 函数,我在其中设置数据源中特定单元格的所有特定内容(即标签和 imageView 的值)。

    然后在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];
    
    
        }
    }
    

    【讨论】:

    • 你能提供更多的代码,还有一些 -(void)configureCell:(UITableViewCell*)cell
    • 如果每个cell都有相同的view,但是有不同的高度,比如imageview有时是20或者是40等等,如何处理。
    • 在configureCell中你可以使用cell.frame = CGRectMake(0, 0, 320, currentHeight);。您还应该返回 tableView:heightForRowAtIndexPath: 中每个单元格的高度
    【解决方案3】:

    Guo Luchuan 的上述答案工作正常,但问题是每次向上和向下滚动时它都会重新创建单元格,如果您的 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
                }
            }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-16
      • 1970-01-01
      • 2012-11-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多