UITableViewCell的重用

可能的错误分析:
在使用UITableViewCell的时候,一般都会重用Cell以提高性能和节省内存开销。但是每个Cell的子控件或者子控件的内容可能会不同,这时重用会导致显示错误(新显示的cell,拥有了它重用的cell的子控件等错误)。

解决办法:

1.子控件不同时,重用时删除cell的子控件,显示新的cell时,重新创建子控件。

2.子控件相同时,无需删除子控件,但重用时对每个子控件重新赋值。

3.cell较少时,无需使用重用机制。


Demo1:这里是错误分析的第一种情况

正确代码,间隔显示如下图色块。


当不考虑去重时,会出现如下情况

其实,核心代码只在ViewController.m中,重用cell的时候删除cell的子控件(或者只删除其子控件的子控件,具体视情况而定)

while ([cell.cellImgView.subviews lastObject] != nil)

    {

     [[cell.cellImgView.subviewslastObject] removeFromSuperview];

    }


下面贴出代码
<pre name="code" class="objc"><pre name="code" class="objc">//
//  XYDTableViewCell.h
//  UITableViewCell重用
//
//  Created by  laisenmi on 10/23/14.
//  Copyright (c) 2014 laisenmi. All rights reserved.
//  自定义的 Cell

#import <UIKit/UIKit.h>

@interface XYDTableViewCell : UITableViewCell
{
    UIView *cellImgView;
}
@property(nonatomic,strong) UIView *cellImgView;
@end


 
  
<pre name="code" class="objc">//
//  XYDTableViewCell.m
//  UITableViewCell重用
//
//  Created by  laisenmi on 10/23/14.
//  Copyright (c) 2014 laisenmi. All rights reserved.
//  自定义的 Cell

#import "XYDTableViewCell.h"

@implementation XYDTableViewCell
@synthesize cellImgView;


-(id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
    if (self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]) {
        self.cellImgView = [[UIView alloc]initWithFrame:self.frame];
        [self addSubview:self.cellImgView];
    }
    return self;
}

@end


 
  
<pre name="code" class="objc">//
//  ViewController.h
//  UITableViewCell重用
//
//  Created by  laisenmi on 10/23/14.
//  Copyright (c) 2014 laisenmi. All rights reserved.
//

#import <UIKit/UIKit.h>

@interface ViewController : UIViewController<UITableViewDataSource,UITableViewDelegate>
{
    UITableView *myTableView;
}
@property(nonatomic,strong) UITableView *myTableView;

@end


 
  
<pre name="code" class="objc">//
//  ViewController.m
//  UITableViewCell重用
//
//  Created by  laisenmi on 10/23/14.
//  Copyright (c) 2014 laisenmi. All rights reserved.
//

#import "ViewController.h"
#import "XYDTableViewCell.h"

@interface ViewController ()

@end

@implementation ViewController
@synthesize myTableView;

- (void)viewDidLoad {
    [super viewDidLoad];
    
    float contentViewW = 305;
    float contentViewH = 337;
    float contentViewX = 7.5;
    float contentViewY = 79;
    CGRect contentViewFrame = CGRectMake(contentViewX, contentViewY, contentViewW, contentViewH);
    self.myTableView = [[UITableView alloc]initWithFrame:contentViewFrame];
    [self.view addSubview:self.myTableView];
    
    self.myTableView.backgroundColor = [UIColor clearColor];
    self.myTableView.separatorStyle = UITableViewCellSeparatorStyleNone;
    self.myTableView.delegate = self;
    self.myTableView.dataSource = self;
    // Do any additional setup after loading the view, typically from a nib.
}

-(XYDTableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *ID = @"cell";
    XYDTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];
    if (cell == nil) {
        cell = [[XYDTableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:ID];
    }
    
    while ([cell.cellImgView.subviews lastObject] != nil) {
        [[cell.cellImgView.subviews lastObject] removeFromSuperview];
    }
    
    if (indexPath.row == 0 || indexPath.row == 2 || indexPath.row == 4 || indexPath.row  == 6 || indexPath.row  == 8 || indexPath.row  == 10  ) {
        float BgOfCoverX = 0;
        float BgOfCoverY = 0;
        float BgOfCoverW = 305;
        float BgOfCoverH = 130;
        CGRect BgOfCoverFrame = CGRectMake(BgOfCoverX, BgOfCoverY, BgOfCoverW, BgOfCoverH);

        UIImageView *BgOfCover = [[UIImageView  alloc]initWithFrame:BgOfCoverFrame];
        BgOfCover.backgroundColor = [UIColor orangeColor];
        [cell.cellImgView addSubview:BgOfCover];

    }
    
    if (indexPath.row == 1 || indexPath.row == 3 || indexPath.row == 5 || indexPath.row == 7 || indexPath.row == 9 || indexPath.row == 11 ) {
        float BgOfCover1X = 0;
        float BgOfCover1Y = 0;
        float BgOfCover1W = 150;
        float BgOfCover1H = 100;
        CGRect BgOfCover1Frame = CGRectMake(BgOfCover1X, BgOfCover1Y, BgOfCover1W, BgOfCover1H);
        
        UIImageView  *BgOfCover1 = [[UIImageView  alloc]initWithFrame:BgOfCover1Frame]; BgOfCover1.backgroundColor = [UIColor greenColor];
        BgOfCover1.backgroundColor = [UIColor redColor];
        [cell.cellImgView addSubview:BgOfCover1];
        
        
        float BgOfCover2X = 155;
        float BgOfCover2Y = 0;
        float BgOfCover2W = 150;
        float BgOfCover2H = 100;
        CGRect BgOfCover2Frame = CGRectMake(BgOfCover2X, BgOfCover2Y, BgOfCover2W, BgOfCover2H);
        
        UIImageView  *BgOfCover2 = [[UIImageView  alloc]initWithFrame:BgOfCover2Frame];
        BgOfCover2.backgroundColor = [UIColor greenColor];
        [cell.cellImgView addSubview:BgOfCover2];



    }
    
    cell.backgroundColor = [UIColor clearColor];
    cell.selectionStyle = UITableViewCellSelectionStyleNone;
    return cell;
}

-(float)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    return 135;
}

-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return 12;
}


@end


 
  
 
 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在使用 `UICollectionView` 或 `UITableView` 时,由于重用机制,可能会导致数据错乱的问题。这是因为当滚动视图滚动时,会将离开屏幕的 `UICollectionViewCell` 或 `UITableViewCell` 放入重用池中,然后再从重用池中取出一个可用的 cell 来显示新的数据,如果没有正确地处理这个过程,就会导致数据错乱的问题。 解决这个问题的方法有多种,下面列举几种常用的方法: 1. 在 `cellForItemAt` 或 `cellForRowAtIndex` 方法中,一定要确保对 cell 的每个子视图进行初始化或设置。例如,设置 label 的文本、image view 的图片等。 2. 在 cell 的 `prepareForReuse` 方法中,清空 cell 中的数据,以便重用时重新设置新的数据。 3. 使用自定义的 cell,而不是系统的默认 cell。在自定义 cell 中,可以更加精细地控制 cell 中的子视图,避免出现数据错乱的问题。 4. 在数据源数组中保存每个 cell 的状态,包括 cell 中每个子视图的状态。在 `cellForItemAt` 或 `cellForRowAtIndex` 方法中,根据数据源数组中保存的状态来设置 cell 的状态,避免出现数据错乱的问题。 5. 使用 `UICollectionViewFlowLayout` 或 `UITableViewFlowLayout` 来实现布局,而不是手动计算 cell 的位置。这样可以避免手动计算 cell 的位置时出现的误差,从而减少数据错乱的问题。 以上是一些常用的解决方法,具体的解决方法还需要根据具体的情况进行调整。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值