2

所以我无法在UITableView. 我确实相信这与重复使用细胞有关。我已经在网上和 SO 上进行了检查,但没有找到适合我的解决方案。任何帮助,将不胜感激。

我有一个由文本和图片填充的数组。然后我将信息显示在tableView. 如果我要使用静态大小的单元格,一切正常,但是文本的数量会发生变化,所以我也实现了该heightForRowAtIndexPath方法。这也有效,直到我一直向下滚动到底部。

之后,当我向上滚动时,所有单元格的高度都会发生变化,并且显示会变得混乱。一些文本被截断,图片被切掉,一些单元格只有文本的最后一部分。我真的认为这与重复使用细胞有关,但我不知道如何解决这个问题。下面是我的cellForRowAtIndexPathand代码heightForRowAtIndexPath

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

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];

if (cell == nil)
{
    cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}

if ([[_theBigArray objectAtIndex:indexPath.row] isKindOfClass:[NSString class]])
{
    NSString *label = [_theBigArray objectAtIndex:indexPath.row];
    CGSize stringSize = [label sizeWithFont:[UIFont systemFontOfSize:15] constrainedToSize:CGSizeMake(320, 9999) lineBreakMode:NSLineBreakByWordWrapping];

    UITextView *textV = [[UITextView alloc] initWithFrame:CGRectMake(5, 5, 290, stringSize.height +50)];
    textV.font = [UIFont systemFontOfSize:15];
    textV.text = [_theBigArray objectAtIndex:indexPath.row];
    textV.textColor = [UIColor blackColor];
    textV.editable = NO;
    [cell.contentView addSubview:textV];
}
else if ([[_theBigArray objectAtIndex:indexPath.row] isKindOfClass:[UIImage class]])
{
    UIImageView *imageV = [[UIImageView alloc] initWithFrame:CGRectMake(5, 5, 290, 100)];
    imageV.contentMode = UIViewContentModeScaleAspectFit;
    imageV.image = [_theBigArray objectAtIndex:indexPath.row];
    [cell.contentView addSubview:imageV];
}

return cell;
[tableView reloadData];
}

为了heightForRowAtIndexPath

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{


int rowHeight = 0.0f;

if ([[_theBigArray objectAtIndex:indexPath.row] isKindOfClass:[NSString class]])
{    
    NSString *temp = [_theBigArray objectAtIndex:indexPath.row];
    CGSize size = [temp sizeWithFont:[UIFont systemFontOfSize:14.0f] constrainedToSize:CGSizeMake(320, 9999) lineBreakMode:NSLineBreakByWordWrapping];
    rowHeight = size.height+50;
}
else if ([[_theBigArray objectAtIndex:indexPath.row] isKindOfClass:[UIImage class]])
{
    rowHeight = 115.0f;
}

//NSLog(@"rowHeight is %i", rowHeight);

return rowHeight;
[tableView reloadData];
}

我什至尝试制作两个不同的单元格并分别调用它们,但同样的事情发生了。我仍然使用相同的heightForRowAtIndexPath方法。

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

UITableViewCell *newCell = [[UITableViewCell alloc] init];

if ([[_theBigArray objectAtIndex:indexPath.row] isKindOfClass:[NSString class]])
{
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell"];

    if (cell == nil)
    {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"Cell"];
    }

    NSString *label = [_theBigArray objectAtIndex:indexPath.row];
    CGSize stringSize = [label sizeWithFont:[UIFont systemFontOfSize:15] constrainedToSize:CGSizeMake(320, 9999) lineBreakMode:NSLineBreakByWordWrapping];
    UITextView *textV = [[UITextView alloc] initWithFrame:CGRectMake(5, 5, 290, stringSize.height +50)];
    textV.font = [UIFont systemFontOfSize:15];
    textV.text = [_theBigArray objectAtIndex:indexPath.row];
    textV.textColor = [UIColor blackColor];
    textV.editable = NO;
    [cell.contentView addSubview:textV];

    newCell = cell;
}
else if ([[_theBigArray objectAtIndex:indexPath.row] isKindOfClass:[UIImage class]])
{
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"PictureCell"];

    if (cell == nil)
    {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"PictureCell"];
    }

    UIImageView *imageV = [[UIImageView alloc] initWithFrame:CGRectMake(5, 5, 290, 100)];
    imageV.contentMode = UIViewContentModeScaleAspectFit;
    imageV.image = [_theBigArray objectAtIndex:indexPath.row];
    [cell.contentView addSubview:imageV];

    newCell = cell;

}

return newCell;
[tableView reloadData];
}

有任何想法吗?

4

1 回答 1

2

主要问题是您每次滚动时都会向单元格添加子视图,但是当一个单元格被重用时,它已经添加了这些子视图。(也就是说,当一个单元格被重用时,它已经有一个 UITextView 或 UIImageView 取决于重用标识符。)

您需要先检查这些子视图是否存在;这通常通过使用-[UIView viewWithTag]方法或通过子类化 UITableViewCell 并将每个视图分配为属性来完成。

(您可以查看 SO 问题How to get other control value from UITableViewCell?了解如何使用 viewWithTag。在您对开箱即用的实现更加熟悉之前,我会避免继承 UITableViewCell。)

另外,这行代码:

UITableViewCell *newCell = [[UITableViewCell alloc] init];

是一个糟糕的主意,因为您正在创建一个新的 UITableViewCell 而没有检查是否可以先重用一个。这违背了重用单元格的全部目的,即快速滚动性能。相反,只需声明它而不初始化它:

UITableViewCell *newCell;

此外,在 heightForRowAtIndexPath 中,您是

  • 声明rowHeightint(应该是CGFloat
  • 在方法返回后尝试调用reloadData(这永远不会发生,但你永远不应该尝试从此方法调用 reloadData)
于 2013-04-23T16:32:55.050 回答