因此,我无法在UITableView
中显示我的数据。我确实认为它与重复使用细胞有关。我已经在网上和SO在这里查了一下,但还没有找到适合我的解决方案。任何帮助,将不胜感激。
我有一个由文本和图片填充的数组。然后我在tableView
中显示信息。如果我使用静态大小的单元格一切正常,但文本数量发生了变化,所以我也实现了heightForRowAtIndexPath
方法。这也有效,直到我一直向下滚动到底部。
之后,当我向上滚动时,所有单元格高度都会改变,显示屏会变得混乱。一些文本被截断,图片被切断,一些单元格只有文本的最后一部分。我真的认为它与重复使用细胞有关,但我不知道如何解决这个问题。以下是我的cellForRowAtIndexPath
和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];
}
有什么想法吗?
答案 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)