Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/116.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 相同的单元格在滚动后重复_Ios_Uitableview - Fatal编程技术网

Ios 相同的单元格在滚动后重复

Ios 相同的单元格在滚动后重复,ios,uitableview,Ios,Uitableview,我使用表视图,使用带有标记的自定义编码方法来节省内存 我成功地在视图中显示了数据,但问题是如果显示了10个单元格,然后如果我向下滚动一个单元格,那么它应该显示2-11个单元格数据,但它会再次切换到1-10 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *cellIdentifier = @"ce

我使用表视图,使用带有标记的自定义编码方法来节省内存

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

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

如果子视图已经创建,则不会将新内容指定给子视图。在case
之后,如果(cell==nil)
,您就得到了引用

cellNAMElabl = (UILabel *)[cell viewWithTag:1];
cellDetaillabl = (UILabel*)[cell viewWithTag:2];
imgView = (UIImageView*)[cell viewWithTag:3];
在这里,当单元格不是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]; 

这种
dequeueReusableCellWithIdentifier
的工作方式是:如果iOS检测到某个单元格不再显示,那么
dequeueReusableCellWithIdentifier
将返回该单元格。如果没有未使用的单元格,则返回nil。因此,您需要做的是:

如果
dequeueReusableCellWithIdentifier
返回nil,则创建一个新单元格,并对具有相同标识符的所有单元格执行所有必要的设置。例如,像以前一样添加视图标记,设置字体、颜色等

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


因此,所有行的所有相同工作在创建单元格时只执行一次,并且只创建在屏幕上显示所需数量的单元格。根据需要为每一行执行不同于每一行的工作

你想做的是

如果单元格为零,则添加/设置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;
}

希望这对你有帮助,快乐编码干杯

如果在If cell==nil块中设置断点,则只有在reuseID正确的情况下,才可能对第一个断点集命中断点。这就是为什么它从来没有机会将任何新数据设置到单元格中

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

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


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

添加这些行,并将它们从“if(cell==nil)”部分中删除。Yup。你说得对@gnasher729。谢谢你指出!我会更新我的答案。