表格查看出列单元格的问题

时间:2013-04-23 16:18:30

标签: ios objective-c uitableview

因此,我无法在UITableView中显示我的数据。我确实认为它与重复使用细胞有关。我已经在网上和SO在这里查了一下,但还没有找到适合我的解决方案。任何帮助,将不胜感激。

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

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

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

有什么想法吗?

1 个答案:

答案 0 :(得分: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中,你是

  • rowHeight声明为int(应该是CGFloat
  • 尝试在方法返回后调用reloadData(这将永远不会发生,但你永远不应该尝试从此方法调用reloadData)