7

我创建了一个多选列表,允许选择多种成分。

在我的表格视图中,可以根据成分的列表属性启用或禁用单元格。如果设置了成分的列表属性,则单元格将被禁用。

但是,当重新使用一个单元格时,它并没有像我预期的那样显示。下面的图片比我更有效地解释了这个问题。

(不应启用的成分是:蛋糕糖霜、炼乳和香粉。)

  1. 第一张图片显示了三种成分按预期禁用和注释。

  2. 但是,在第二张图片中,向下滚动显示某些成分显示为已禁用(但您可以选择它们,并且它们具有完整的交互作用)。

  3. 第三张图片显示了向上滚动到顶部后的列表。一些成分已显示为灰色,请注意玉米粉是如何显示为启用的,即使您无法交互/选择它。

问题与细胞重用有关。重复使用时,单元格似乎没有“重置”,因此保留了它的一些“旧”外观。

下面是来自 的代码cellForRowAtIndexPath:,因为我确定这就是问题所在(尽管我看不出有什么问题)。

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

    // Fetches the corresponding Ingredient from the ingredientArray
    Ingredient *ingredient = [self.ingredientArray objectAtIndex:indexPath.row];

    if ([ingredient.list isEqualToString:@"Lardr"])
    {
        cell.userInteractionEnabled = NO;
        cell.detailTextLabel.text = @"   Already in your Lardr";
    }
    else if ([ingredient.list isEqualToString:@"Shopping List"])
    {
        cell.userInteractionEnabled = NO;
        cell.detailTextLabel.text = @"   Already on your Shopping List";
    }
    else
    {
        cell.userInteractionEnabled = YES;
        cell.detailTextLabel.text = @"";
    }

    // Add a checkmark accessory to the cell if the ingredient is on the selectedIngredients array
    if ([self.selectedIngredients containsObject:ingredient])
        cell.accessoryType = UITableViewCellAccessoryCheckmark;
    else
        cell.accessoryType = UITableViewCellAccessoryNone;

    cell.textLabel.text = ingredient.name;

    return cell;
}

我想尽办法解决这个问题,我已经阅读了所有甚至远程相关的 SO 问题,但无济于事。有什么问题?!


我的逻辑是,对于每个单元格,都设置了 textLabel、detailTextLabel、userInteractionEnabled 和 accessoryType 属性,无论通过 if 语句的哪个执行路径,所以我看不出为什么,即使在重用之后,单元格也不能正确显示。


编辑:为了找出问题的根源,我尝试通过在获取相应成分的行上方添加以下内容,将单元格“重置”回默认值:但无济于事。

cell.userInteractionEnabled = YES;
cell.textLabel.text = nil;
cell.detailTextLabel.text = nil;
cell.accessoryType = UITableViewAccessoryNone;

但是,有趣且完全不合逻辑的地方-当我将以下行cell.textLabel.text = ingredient.name移到读取行的正下方Ingredient *ingredient = [self.ingredientArray objectAtIndex:indexPath.row];时,即使在下面进一步设置了 userInteraction (并且相关单元格按预期禁用),也绝对不会将样式应用于任何单元格.

我在想,设置单元格属性的顺序重要吗?我知道不应该,但外观会根据上述情况发生变化。


更新:我已经解决了这个问题;请参阅下面的答案。

4

4 回答 4

2

在willDisplayCell中明确设置单元格的颜色

- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath{

 Ingredient *ingredient = [self.ingredientArray objectAtIndex:indexPath.row];

    if ([ingredient.list isEqualToString:@"Lardr"])
    {
        cell.textLabel.textColor = [UIColor lightGrayColor];
    }
    else if ([ingredient.list isEqualToString:@"Shopping List"])
    {
        cell.textLabel.textColor = [UIColor lightGrayColor];
    }
    else
    {
        cell.textLabel.textColor = [UIColor blackColor];
    }

}
于 2013-04-03T10:32:08.800 回答
2

我已经解决了这个问题。问题是我在设置单元格文本之前设置了 userInteractionEnabled(感谢评论中 Carl Veazey的链接)。

我通过在调整 userInteractionEnabled 属性之前设置单元格的文本来解决此问题。但是,没有对单元格应用样式(即使该单元格被禁用)。因此,我必须通过设置单元格的 textColor 来手动设置单元格的样式。下面是带有注释的调整后的代码。

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

    // Fetches the relevent ingredient from the ingredientArray
    Ingredient *ingredient = [self.ingredientArray objectAtIndex:indexPath.row];
    cell.textLabel.text = ingredient.name; // Moved this line before setting userInteractionEnabled

    if ([ingredient.list isEqualToString:@"Lardr"])
    {
        cell.userInteractionEnabled = NO;
        cell.detailTextLabel.text = @"   Already in your Lardr";
        cell.textLabel.textColor = [UIColor grayColor]; // Update the color accordingly
    }
    else if ([ingredient.list isEqualToString:@"Shopping List"])
    {
        cell.userInteractionEnabled = NO;
        cell.detailTextLabel.text = @"   Already on your Shopping List";
        cell.textLabel.textColor = [UIColor grayColor];
    }
    else
    {
        cell.userInteractionEnabled = YES;
        cell.detailTextLabel.text = @"";
        cell.textLabel.textColor = [UIColor blackColor];
    }

    // Add a checkmark accessory to the cell if the ingredient is on the selectedIngredients array
    if ([self.selectedIngredients containsObject:ingredient])
        cell.accessoryType = UITableViewCellAccessoryCheckmark;
    else
        cell.accessoryType = UITableViewCellAccessoryNone;

    return cell;
}

显然,设置单元格属性的顺序应该是无关紧要的,所以我确信这是一个错误。希望这对遇到同样问题的其他人有所帮助。

于 2013-04-03T16:48:20.897 回答
0

维护表格视图中选定单元格的列表,在重用单元格时只需检查单元格是否已在选择列表中。如果是,只需在那里进行自定义。像这样试试。

宣言

 TableViewCell *_selectedCell; 

自定义行以存储选定的单元格并维护选择列表。

_selectedCell = (TableViewCell*)[self.ItemTable cellForRowAtIndexPath:[NSIndexPath indexPathForRow:rowIndex inSection:0]];

在 cellForRowAtIndexPath 检查当前单元格是否在

if(_selectedCell)
        [cell setBackgroundColor:[UIColor whiteColor]];// Customize the cell 
于 2013-04-03T03:53:02.050 回答
0

将以下代码与情节提要中的表视图控制器一起使用,一切正常。似乎在不使用情节提要时默认获得的表格视图存在一些错误:

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

    // Fetches the corresponding Ingredient from the ingredientArray
    Ingredient *ingredient = [self.ingredientArray objectAtIndex:indexPath.row];

    if ([ingredient.list isEqualToString:@"Lardr"])
    {
        cell.userInteractionEnabled = NO;
        cell.detailTextLabel.text = @"   Already in your Lardr";
        cell.textLabel.textColor = [UIColor lightGrayColor];
    }
    else if ([ingredient.list isEqualToString:@"Shopping List"])
    {
        cell.userInteractionEnabled = NO;
        cell.detailTextLabel.text = @"   Already on your Shopping List";
        cell.textLabel.textColor = [UIColor lightGrayColor];
    }
    else
    {
        cell.userInteractionEnabled = YES;
        cell.detailTextLabel.text = @"";
        cell.textLabel.textColor = [UIColor blackColor];
    }

    if ([self.selectedIngredients containsObject:ingredient])
        cell.accessoryType = UITableViewCellAccessoryCheckmark;
    else
        cell.accessoryType = UITableViewCellAccessoryNone;

    cell.textLabel.text = ingredient.name;

    return cell;
}

请注意,我使用 dequeueReusableCellWithIdentifier:forIndexPath: 而不是 dequeueReusableCellWithIdentifier:,并消除了 if 子句。这与您的问题没有任何关系,但它是为情节提要中的表格视图执行此操作的最新方法。

于 2013-04-03T03:54:14.860 回答