重复使用的单元格不断获得双重标签

时间:2015-02-01 11:13:42

标签: ios objective-c uitableview

所以,我正在尝试使用自定义单元格实现UITableView。但是,当我滚动文本被覆盖在重用单元格中的其他文本时。

这是我构建细胞的方式:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString * reuseIdentifier = @"programmaticCell";
    MGSwipeTableCell * cell = [self.tableView dequeueReusableCellWithIdentifier:reuseIdentifier];
    if (!cell) {
        cell = [[MGSwipeTableCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:reuseIdentifier];
    }

    CGFloat brightness = [UIScreen mainScreen].brightness;

    if (brightness < 0.4) {
        cell.backgroundColor = [UIColor darkGrayColor];
        cell.textLabel.textColor = [UIColor whiteColor];
        cell.detailTextLabel.textColor = [UIColor whiteColor];
    }

    NSString *imageUrl = [NSString stringWithFormat: @"%@", [self.streams[indexPath.row] plaatje]];

    UIImageView *image = [[UIImageView alloc] initWithFrame:CGRectMake(5, 5, 55, 55)];
    __block UIActivityIndicatorView *activityIndicator;
    __weak UIImageView *weakImageView = image;
    [image sd_setImageWithURL: imageUrl
             placeholderImage:[UIImage imageNamed:@"tile-blue.png"]
                      options:SDWebImageProgressiveDownload
                     progress:^(NSInteger receivedSize, NSInteger expectedSize) {
                         if (!activityIndicator) {
                             [weakImageView addSubview:activityIndicator = [UIActivityIndicatorView.alloc initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray]];
                         activityIndicator.center = weakImageView.center;
                             [activityIndicator startAnimating];
                         }
                     }
                    completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) {
                        [activityIndicator removeFromSuperview];
                        activityIndicator = nil;
                    }];
    UIView *cellView=[[UIView alloc]initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, 65)];
    [cellView addSubview:image ];

    UILabel *nameLabel = [[UILabel alloc] initWithFrame:CGRectMake(65, 15, self.view.frame.size.width, 20)];
    nameLabel.text = [[self.streams[indexPath.row] name] capitalizedString];
    nameLabel.textAlignment = NSTextAlignmentLeft;
    nameLabel.font = [UIFont systemFontOfSize:20];

    UILabel *publishLabel = [[UILabel alloc] initWithFrame:CGRectMake(65, 35, 100, 20)];
    publishLabel.text = [[self.streams[indexPath.row] published] capitalizedString];
    publishLabel.textAlignment = NSTextAlignmentLeft;
publishLabel.font = [UIFont systemFontOfSize:13];

    if (brightness < 0.4) {
        nameLabel.textColor = [UIColor whiteColor];
        publishLabel.textColor = [UIColor whiteColor];
    } else {
        nameLabel.textColor = [UIColor blackColor];
        publishLabel.textColor = [UIColor blackColor];
    }

    [cellView addSubview:nameLabel];
    [cellView addSubview:publishLabel];

    [cell addSubview:cellView];
    [cell sendSubviewToBack:cellView];

    cell.delegate = self; //optional

    return cell;
}

这是我重写的MGSwipeTableCell prepareForReuse方法:

-(void) prepareForReuse
{
    [super prepareForReuse];

    self.textLabel.text = nil;
    self.detailTextLabel.text = nil;
    self.imageView.image = nil;

    [self cleanViews];
    BOOL cleanButtons = _delegate && [_delegate respondsToSelector:@selector(swipeTableCell:swipeButtonsForDirection:swipeSettings:expansionSettings:)];
    [self initViews:cleanButtons];
}

我在这里做错了什么?

2 个答案:

答案 0 :(得分:0)

您的问题可能是因为您每次都在重新创建单元格的项目。

尝试对UITableViewCell进行子类化并将所有代码移入其中。设置所有标签/ imageViews /等的属性。您甚至可以创建一个xib并使用autolayout和IBOutlets来管理单元格的外观。

如果你最终创建了一个xib,只需要知道你必须在tableView类中注册nib才能使用它。

self.tableView registerNib:[UINib nibWithNibName:@"nameOfXibFile" bundle:nil]; forCellReuseIdentifier:@"customIdentifier"];

执行此操作时,每次重复使用单元格并且不会创建新对象时,它将引用相同的标签/图像/ etc对象。

答案 1 :(得分:0)

每次调用方法时,都会尝试将单元格出列。这是正确的。

但是,之后的所有代码都假定您正在获取单元格,这是不正确的。您每次都会制作新标签,并且每次出列的单元格已经有这些标签时,都会将它们添加到单元格中。

使用viewWithTag:来检查标签是否存在(并且仅在他们时创建标签),或者为每个标签创建一个包含属性的自定义表格单元子类

tableview:cellForRowAtIndexPath:的实现需要idempotent,这意味着您应该编写代码,以便可以反复调用多次代码,并始终返回相同的单元格。