UITableViewCell怪异的动作

时间:2014-12-30 19:25:39

标签: ios objective-c uitableview

让我们马上开始使用一些代码:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell"forIndexPath:indexPath];

    Produit *object = self.objects[indexPath.row];
    [cell.contentView addSubview:object];

    return cell;
}

在单元格中,我添加了一个类型为Produit的子视图,它是UIView的子类。这就是它的样子:

image

编辑所有的东西工作正常,除了当有更多的单元格比屏幕的大小允许时。在这种情况下,如果我尝试修改其中一个单元格中的某些信息,就好像新信息被添加到旧信息之上一样:

second image

在此图片中,只有Button表现得很怪异,但有时文本字段也会显示在彼此的顶部。更重要的是,如果我在顶部修改单元格,那么如果我滚动到表格视图的底部,最后一个单元格也会被修改。最后一件事:当我在产生这个故障后添加更多单元格时,一些新单元格与闪烁单元格相同的“类别”,就像它正在制作它的副本并将“类别”放入闪烁的标题中......

有人可以解释发生了什么吗?我该如何解决?这里有一些代码(不是全部,只是表视图配置)

-(void) addNewProduit:(UIBarButtonItem*) item {
    if (!self.objects) {
        self.objects = [[NSMutableArray alloc] init];
    }
    Produit* product = [[Produit alloc] init];
    CGRect frame = CGRectMake(0, 0, self.frame.size.width, 44);
    [product setFrame:frame];
    [product initView];
    [self.objects insertObject:product atIndex:0];
    NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:0];

    [self.tableView insertRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
}

- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
    // Return NO if you do not want the specified item to be editable.
    return YES;
}

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
    if (editingStyle == UITableViewCellEditingStyleDelete) {
        [self.objects removeObjectAtIndex:indexPath.row];
        [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
    } else if (editingStyle == UITableViewCellEditingStyleInsert) {
        // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view.
    }
}

2 个答案:

答案 0 :(得分:2)

dequeueReusableCellWithIdentifier: forIndexPath:为您提供了一个可能是新单元格的单元格,或者它可能是以前显示过的旧单元格,但已从屏幕滚动。

一个快速解决方法是:

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell"forIndexPath:indexPath];

Produit *object = self.objects[indexPath.row];

[cell.contentView.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)];
[cell.contentView addSubview:object];

return cell;

这将以最低效的方式解决您的问题。当您滚动得非常快时,它可能会导致抖动动画,尤其是在旧设备上。我只是想把它作为你需要解决的问题的一个例子。

如果视图已经存在,那么更合适的解决方案将重用该视图,而不是每次都创建一个新视图。

self.objects似乎包含视图,这违背了UITableView真正快速滚动设置的目的。您应该只在那里包含数据对象,然后在显示一个单元格时配置单个单元格的视图。 IE,你不希望每个数据对象都有一个视图,你想要6个视图来适应当前需要显示的数据对象。

答案 1 :(得分:1)

当您按[cell.contentView addSubview:object];重复使用单元格时,您总是会添加更多观看次数。一种解决方案可能是在添加视图时标记视图,然后在添加另一个视图之前删除任何具有相应标记的子视图。