滚动后重复相同的细胞

时间:2015-05-30 10:32:37

标签: ios uitableview

我正在使用表格视图使用自定义编码和标记方法来节省内存。

我成功地在视图中显示数据,但问题是如果显示10个单元格然后如果我向下滚动一个单元格那么它应该显示2-11单元格数据但它再次切换到1-10。 / p>

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *cellIdentifier = @"cellID";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
    UILabel *cellNAMElabl = nil;
    UILabel *cellDetaillabl = nil;
    UIImageView *imgView = nil;

    if (cell == nil) {
        cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellIdentifier];

        cellNAMElabl = [[UILabel alloc] initWithFrame:CGRectMake(88, 10, 150, 20)];
        [cellNAMElabl setTag:1];
        cellNAMElabl.text = [name5 objectAtIndex:indexPath.row];
        UIFont *myFont1 = [ UIFont fontWithName: @"Arial" size: 20.0 ];
        cellNAMElabl.font  = myFont1;
        [cell.contentView addSubview:cellNAMElabl];

        cellDetaillabl = [[UILabel alloc] initWithFrame:CGRectMake(88, 28, 150, 20)];
        [cellDetaillabl setTag:2];
        cellDetaillabl.text = [email5 objectAtIndex:indexPath.row];
        UIFont *myFont = [ UIFont fontWithName: @"Arial" size: 13.0 ];
        cellDetaillabl.font  = myFont;
        [cell.contentView addSubview:cellDetaillabl];

        imgView=[[UIImageView alloc] initWithFrame:CGRectMake(25, 5, 52, 50)];
        [imgView setTag:3];

        imgView.image = [imagepath5 objectAtIndex:indexPath.row];
        [cell.contentView addSubview:imgView];
    }

    cellNAMElabl = (UILabel *)[cell viewWithTag:1];
    cellDetaillabl = (UILabel*)[cell viewWithTag:2];
    imgView = (UIImageView*)[cell viewWithTag:3];

    cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;

    return cell;
}

4 个答案:

答案 0 :(得分:1)

如果已经创建了子视图,则不会将新内容分配给子视图。在案例if(cell == nil)之后,您刚刚获得了参考资料。

cellNAMElabl = (UILabel *)[cell viewWithTag:1];
cellDetaillabl = (UILabel*)[cell viewWithTag:2];
imgView = (UIImageView*)[cell viewWithTag:3];

这里当cell不是nil时,你只是引用了标签和imageview,但是你没有从数据源设置新的文本和图像。添加以下行并将其从if (cell == nil)部分删除:

cellNAMElabl.text = [name5 objectAtIndex:indexPath.row];
cellDetaillabl.text = [email5 objectAtIndex:indexPath.row];
imgView.image = [imagepath5 objectAtIndex:indexPath.row];
                     [cell.contentView addSubview:imgView]; 

答案 1 :(得分:1)

dequeueReusableCellWithIdentifier的工作方式:如果iOS检测到单元格不再显示,则dequeueReusableCellWithIdentifier将返回该单元格。如果没有未使用的单元格,则返回nil。那么你需要做什么:

如果dequeueReusableCellWithIdentifier返回nil,则创建一个新单元格,然后执行具有相同标识符的所有单元格所需的所有设置。例如,像你一样添加视图标签,设置字体,颜色等。

然后,无论您使用dequeueReusableCellWithIdentifier返回的单元格还是您刚刚创建的单元格,都可以添加用于要显示的特定部分/行的所有信息。因此,如果第1行,第2行等显示不同的文本,则在此处设置文本。这就是你没有做的,所以当一个单元被重用时,你没有为它设置新的文本。

所以我们的想法是,所有行的所有工作都只在创建一个单元格时一次完成,并且只创建了所需数量的单元格,以便在屏幕。根据需要,每行都会执行不同行的工作。

答案 2 :(得分:0)

你想要做的是......

如果单元格为nil,则添加/设置tableViewCell UI。

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *cellIdentifier = @"cellID";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];

    if (cell == nil) {
        cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellIdentifier];

        UILabel *cellNAMElabl = [[UILabel alloc] initWithFrame:CGRectMake(88, 10, 150, 20)];
        cellNAMElabl.tag = 1;
        cellNAMElabl.font  = [UIFont fontWithName: @"Arial" size: 20.0 ];
        [cell.contentView addSubview:cellNAMElabl];

        UILabel *cellDetaillabl = [[UILabel alloc] initWithFrame:CGRectMake(88, 28, 150, 20)];
        cellDetaillabl.tag = 2;
        cellDetaillabl.font  = [UIFont fontWithName: @"Arial" size: 13.0 ];
        [cell.contentView addSubview:cellDetaillabl];

        UIImageView *imgView=[[UIImageView alloc] initWithFrame:CGRectMake(25, 5, 52, 50)];
        imgView.tag = 3;
        [cell.contentView addSubview:imgView];
    }

//and just update your data if the cell is currently exist and not nil..
//you already called the view using tag so, you dont need those:
//    UILabel *cellNAMElabl = nil;
//    UILabel *cellDetaillabl = nil;
//    UIImageView *imgView = nil;

    ((UILabel *)[cell viewWithTag:1]).text = [name5 objectAtIndex:indexPath.row]; // cellNAMElabl
    ((UILabel*)[cell viewWithTag:2]).text = [email5 objectAtIndex:indexPath.row]; // cellDetaillabl
    ((UIImageView*)[cell viewWithTag:3]).image = [imagepath5 objectAtIndex:indexPath.row]; // imgView

    cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;

    return cell;
}

希望这对你有所帮助,快乐的编码欢呼!

答案 3 :(得分:0)

如果你在if cell == nil块中设置一个断点,如果你的reuseID正确,它可能只会被第一组命中。这就是为什么它永远不会有机会将任何新数据设置到单元格中。

您不应该查找nil单元格,而是在IB中使用正确的reuseID和原型单元格,该单元格设置为您创建的自定义UITableViewCell子类。

在自定义单元格上实施prepareForReuse也是一种很好的做法,您可以在其中清除任何单元格数据,例如label.text = nil, imageview.image = nil

这样您就不会从先前出列的单元格中获取无效数据。它可能无法直接解决问题,但它会擦除if cell == nil块中的固定数据集以帮助调试。