如何避免UITableViewCell重复添加自定义标签时,TableView滚动?

我创build一个自定义单元格:

#import <UIKit/UIKit.h> #import "RecruitmentResumeEntity.h" @interface RecruimentListItemCell : UITableViewCell @property (nonatomic, strong) RecruitmentResumeEntity *entity; @end 

在.m文件中设置实体方法我添加三个标签:

 -(void)setEntity:(RecruitmentResumeEntity *)entity { _entity = entity; float labelHeight = 17; CGRect frame = CGRectMake(64, 45, 0, labelHeight); UILabel *cityLabel = [self createTagLabelWithFrame:frame text:_entity.city backgroundColor:@"#e5986f"]; [self.contentView addSubview:cityLabel]; UILabel *workExperienceLabel = [self createTagLabelWithFrame:CGRectMake(cityLabel.x+cityLabel.width +10, cityLabel.y, 0, labelHeight) text:[NSString stringWithFormat:@"%@年",_entity.workExperience] backgroundColor:@"#81A0D7"]; [self.contentView addSubview:workExperienceLabel]; UILabel *expectSalaryLabel = [self createTagLabelWithFrame:CGRectMake(workExperienceLabel.x+workExperienceLabel.width +10, workExperienceLabel.y, 0, labelHeight) text:_entity.expectSalary backgroundColor:@"#94C373"]; [self.contentView addSubview:expectSalaryLabel]; } 

在Controller cellForRowAtIndexPath方法中获取自定义单元格并设置实体。 但是当我运行应用程序,滚动UITableView时,我发现单元格重复创build三个标签,我只是希望每个单元格只有三个标签。 我有什么错误或失踪 任何人都可以帮助我吗? 等待你的帮助。谢谢。 在这里输入图像说明

 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { RecruitmentResumeEntity *entity = _dataList[indexPath.row]; RecruimentListItemCell *cell = [tableView dequeueReusableCellWithIdentifier:@"RecruimentListItemCell" forIndexPath:indexPath]; cell.entity = entity; return cell; } 

这似乎是一个问题,你不正确地重新使用单元格。

当你调用RecruimentListItemCell *cell = [tableView dequeueReusableCellWithIdentifier:@"RecruimentListItemCell" forIndexPath:indexPath]; 系统会将您认为可以重新使用的单元格传递给需要显示的下一个单元格的信息,但单元格的使用完全由您负责,因此在重新使用它之前,请先准备好这个单元格。

为此,您将必须在-(void)prepareForReuse中实现-(void)prepareForReuse ,在那里您必须确保所有需要在单元中重新填充的项目都被正确地重置,以便可以正确地重新填充单元格。

例如,如果在RecruimentListItemCell中添加一个标签“SampleLable”作为一个子视图,但是你不在-(void)prepareForReuse执行[SampleLable removeFromSuperView] ,那么每当单元格被重用时,“SampleLable”会再次被添加到它最后你会注意到事情不像他们应该看的那样,就像你的“重复创build标签”一样

这是prepareForReuse在我的一个应用程序中的外观:

 -(void)prepareForReuse { [super prepareForReuse]; [_statesView.activityIcon1 setHidden:YES]; [_statesView.activityIcon2 setHidden:YES]; _title.text = nil; _infoText.text = nil; _createdTime.text = nil; _cellType = CustomCellTypeNone; [_progressView setProgress:0]; } 

在这里你可以看到有些项目我只是设置为零(并不总是最好的方法),如果需要的话,这些只是再次放入。 你可以看到我隐藏了activityIcon 1和2.当下一个单元格出现时,如果它需要图标,它只是取消隐藏它们,如果它需要标签,那么它会添加它们。

所以,如果我不删除所有的标签,会发生什么,他们留在视图中,下一个单元格可能会添加自己的标签,这将导致您遇到的问题。

您可以将这三个标签作为RecruimentListItemCell属性,并使用延迟加载对它们进行初始化。

 - (UILabel *)cityLabel { if (!_cityLabel) { _cityLabel = [self createTagLabelWithFrame:frame text:nil backgroundColor:@"#e5986f"]; [self.contentView addSubview:cityLabel]; } return _cityLabel; } - (UILabel *)workExperienceLabel { if (!_workExperienceLabel) { _workExperienceLabel = [self createTagLabelWithFrame:CGRectMake(cityLabel.x+cityLabel.width +10, cityLabel.y, 0, labelHeight) text:nil backgroundColor:@"#81A0D7"]; [self.contentView addSubview:workExperienceLabel]; } return _workExperienceLabel; } - (UILabel *)expectSalaryLabel { if (!_expectSalaryLabel) { _expectSalaryLabel = [self createTagLabelWithFrame:CGRectMake(workExperienceLabel.x+workExperienceLabel.width +10, workExperienceLabel.y, 0, labelHeight) text:_entity.expectSalary backgroundColor:@"#94C373"]; [self.contentView addSubview:expectSalaryLabel]; } return _expectSalaryLabel; } 

你只需要在select符setEntity:为这些标签设置setEntity:

 -(void)setEntity:(RecruitmentResumeEntity *)entity { _entity = entity; float labelHeight = 17; [self.cityLabel setText:_entity.city]; [self.workExperienceLabel setText:[NSString stringWithFormat:@"%@年",_entity.workExperience]]; self.expectSalaryLabel setText:_entity.expectSalary]; } 

为了更好的重用,你可以覆盖select器prepareForReuse

 - (void)prepareForReuse { [super prepareForReuse]; _cityLabel.text = nil; _workExperienceLabel.text = nil; _expectSalaryLabel.text = nil; } 

此外,您可以覆盖布局的select器layoutSubviews

 - (void)layoutSubviews { [super layoutSubviews]; } 

这是因为tableView重复使用单元格,所以它重复创build你的UILabel,你可以在创build它之前删除三个UILabel!

在生成任何单元格之前,您可以通过比较cell == nil条件来使用它。

 static NSString *recruitmentTableIdentifier = @"RecruimentListItemCell"; RecruimentListItemCell *cell = [tableView dequeueReusableCellWithIdentifier:recruitmentTableIdentifier]; if (cell == nil) { cell = [[RecruimentListItemCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:recruitmentTableIdentifier]; } 

希望,它会工作。
谢谢。