表视图麻烦与出列单元格

所以我无法在UITableView显示数据。 我相信这与重用单元格有关。 我已经在网上查询,但没有find适合我的解决scheme。 任何帮助,将不胜感激。

我有一个由文本和图片填充的数组。 我然后在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]; } 

有任何想法吗?

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

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

(你可以看看这个SO问题如何从UITableViewCell获得其他的控制值?看看如何使用viewWithTag。我会避免inheritanceUITableViewCell,直到你更熟悉开箱即用的实现。

另外,这行代码:

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

是一个可怕的想法,因为你正在创build一个新的UITableViewCell而不检查是否可以重用一个。 这打破了重复使用单元的全部目的,这是快速滚动的performance。 相反,只需声明它,而不需要初始化它:

 UITableViewCell *newCell; 

另外,在heightForRowAtIndexPath,你是

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