Iphone 为什么在tableview中将标记更改为重用单元格

Iphone 为什么在tableview中将标记更改为重用单元格,iphone,xcode,ipad,sqlite,Iphone,Xcode,Ipad,Sqlite,我正在创建自定义单元格containUILabel,UIImageView,为UILabel使用常量标记,UIImageView使用动态标记,表格有11个单元格,前7个单元格加载正确,当我分别更改表格中的1、2、3、4个单元格时,8、9、10、11个单元格的图像视图会发生变化,此外,单元格中的标记相同,我使用表中的“图像”复选框,UITapGestureRecognizer用于更改表中的图像视图 我正在使用此代码 - (UITableViewCell *)tableView:(UITableVi

我正在创建自定义单元格contain
UILabel
UIImageView
,为
UILabel
使用常量标记,
UIImageView
使用动态标记,表格有11个单元格,前7个单元格加载正确,当我分别更改表格中的1、2、3、4个单元格时,8、9、10、11个单元格的图像视图会发生变化,此外,单元格中的标记相同,我使用表中的“图像”复选框,
UITapGestureRecognizer
用于更改表中的图像视图

我正在使用此代码

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    static NSString *CellIdentifier =@"Cell";
    UITableViewCell *cell = [tableview dequeueReusableCellWithIdentifier:CellIdentifier];


    if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] ;
        cell.selectionStyle=UITableViewCellSelectionStyleGray;
        cell.accessoryType=UITableViewCellAccessoryDisclosureIndicator;
        UIImageView *imageview=[[UIImageView alloc]initWithFrame:CGRectMake(5, 12, 20, 20)];
        imageview.tag=n;
        [cell.contentView addSubview:imageview]; 
        UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tabimage:)];
        imageview.userInteractionEnabled=YES;
        [imageview addGestureRecognizer:tap];
        imageview.image=[UIImage imageNamed:@"img1.jpeg"];

        UILabel *titleLabel=[[UILabel alloc]initWithFrame:CGRectMake(30, 2, 260,26)];
        titleLabel.tag=222;
        titleLabel.backgroundColor=[UIColor clearColor];
        [cell.contentView addSubview:titleLabel];

        UILabel *dateLabel=[[UILabel alloc]initWithFrame:CGRectMake(30, 31, 260, 13)];
        dateLabel.tag=333;
        dateLabel.font=[UIFont systemFontOfSize:10];
        dateLabel.backgroundColor=[UIColor clearColor];
         [cell.contentView addSubview:dateLabel];
    }
    UIImageView *imageview1=(UIImageView*)[cell.contentView viewWithTag:n];
    if([array containsObject:[NSNumber numberWithInt:imageview1.tag]]) {
       imageview1.image=[UIImage imageNamed:@"img2.jpeg"];  
    } else {
       imageview1.image=[UIImage imageNamed:@"img1.jpeg"];   
    }

    UILabel *titlelable=(UILabel*)[cell.contentView viewWithTag:222];
    titlelable.text=[task objectAtIndex:indexPath.section];
    NSLog(@"%i",indexPath.section);

    UILabel *dateLabel=(UILabel*)[cell.contentView viewWithTag:333];
    dateLabel.text=[date objectAtIndex:indexPath.section];
    n++;
    return  cell;
}

- (void)tabimage:(id)sender {
    UIImageView *iv=(UIImageView *)[sender view];
    int i=iv.tag;
    NSLog(@"------------%i",i);
   if (iv.image==[UIImage imageNamed:@"img1.jpeg"]) {
       iv.image= [UIImage imageNamed:@"img2.jpeg"];
       [array addObject:[NSNumber numberWithInt:i]];
   } else {
      iv.image= [UIImage imageNamed:@"img1.jpeg"];  
      [array removeObject:[NSNumber numberWithInt:i]];
    }
  }

不管你看到什么问题,使用“
n
”很可能就是问题所在。没有充分的理由使用共享变量来标记(和检索)表视图单元格上的视图

-(UITableViewCell*)tableView:(UITableView*)tableView cellForRowAtIndexPath:(nsindepath*)indepath
被多次调用,同一个单元格可能会被多次调用,有时会找到要重用的单元格,有时则不会

我当然不知道
n
是什么,也不知道在代码的其他地方如何使用它,但是每次调用时都会更改它,并且在调用此方法时无法做出假设,因此它毫无价值

您肯定知道每个单元格都有一个带有该标记的图像,但是在第一次运行该方法后是否可以访问该图像是完全未定义的,因此每次重用基本上都会出现随机行为(一个新的单元格或一个带有您不知道的标记的重用单元格)


问问你自己(或者在另一个问题上问自己):你想在这里实现什么?

你应该将你的单元格标识符从静态改为动态,这样可以解决你的问题

你应该把这个换掉

static NSString *CellIdentifier =@"Cell";
UITableViewCell *cell = [tableview dequeueReusableCellWithIdentifier:CellIdentifier];
用这个

UITableViewCell *cell = [tableview dequeueReusableCellWithIdentifier:[NSString stringWithFormat:@"%d %d"], indexPath.row, indexPath.section];

我建议将UITableViewCell子类化,在那里添加所有自定义元素,并为其创建setter。在cellForRowAtIndexPath中,只需呼叫您的设定者

当您在if(cell==nil)块中将标记设置为imageview时,意味着将在创建单元格时设置标记。在您的例子中,7个单元被创建,然后这些单元被排队重用。因此,从8开始,将使用先前创建的单元格。这就是为什么8、9、10…单元格的标签与1、2、3…相同

Alex建议了一个标准的方法。但是如果您还没有使用自定义单元格,您可以尝试此方法-

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    static NSString *CellIdentifier =@"Cell";
    UITableViewCell *cell = [tableview dequeueReusableCellWithIdentifier:CellIdentifier];
    UIImageView *imageview = nil;    
    if(cell){
        for (UIView *view in cell.contentView.subviews){
            if([view isKindOfClass:[UIImageView class]]){
                    imageview = (UIImageView*)view;
                    break;
            }
        }
    }

    if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] ;
        cell.selectionStyle=UITableViewCellSelectionStyleGray;
        cell.accessoryType=UITableViewCellAccessoryDisclosureIndicator;
        imageview=[[UIImageView alloc]initWithFrame:CGRectMake(5, 12, 20, 20)];
        [cell.contentView addSubview:imageview]; 
        UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tabimage:)];
        imageview.userInteractionEnabled=YES;
        [imageview addGestureRecognizer:tap];
        imageview.image=[UIImage imageNamed:@"img1.jpeg"];

        UILabel *titleLabel=[[UILabel alloc]initWithFrame:CGRectMake(30, 2, 260,26)];
        titleLabel.tag=222;
        titleLabel.backgroundColor=[UIColor clearColor];
        [cell.contentView addSubview:titleLabel];

        UILabel *dateLabel=[[UILabel alloc]initWithFrame:CGRectMake(30, 31, 260, 13)];
        dateLabel.tag=333;
        dateLabel.font=[UIFont systemFontOfSize:10];
        dateLabel.backgroundColor=[UIColor clearColor];
         [cell.contentView addSubview:dateLabel];
    }
    imageview.tag=n;
    if([array containsObject:[NSNumber numberWithInt:imageview.tag]]) {
       imageview.image=[UIImage imageNamed:@"img2.jpeg"];  
    } else {
       imageview.image=[UIImage imageNamed:@"img1.jpeg"];   
    }

    UILabel *titlelable=(UILabel*)[cell.contentView viewWithTag:222];
    titlelable.text=[task objectAtIndex:indexPath.section];
    NSLog(@"%i",indexPath.section);

    UILabel *dateLabel=(UILabel*)[cell.contentView viewWithTag:333];
    dateLabel.text=[date objectAtIndex:indexPath.section];
    n++;
    return  cell;
}

我正在为我的应用程序获取解决方案

在我的代码中使用动态单元格标识符

NSString *CellIdentifier =[NSString stringWithFormat:@"%i-%i", indexPath.section,indexPath.row];

... 然后呢?您的问题是什么?它正常工作NSString*CellIdentifier=[NSString stringWithFormat:@“%i-%i”,indexath.section,indexPath.row];同意,我看不到
n
设置在代码中的任何地方,所以即使有这么多的代码块,我们也不能完全知道发生了什么。这正是我的答案,你当时为什么不接受我的答案。