出列单元格的表视图问题 [英] Table View troubles with dequeue cell

查看:21
本文介绍了出列单元格的表视图问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

So I am having trouble showing my data in a UITableView. I do believe it has something to do with reusing the cells. I have checked online and here at SO but have not found a solution that works for me. Any help would be appreciated.

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

I have an Array that is populated by text and pictures. I am then showing the information in a tableView. If I were to use static sized cells everything works out fine, but the amount of text changes, so I have also implemented the heightForRowAtIndexPath method. This works as well, until I scroll all the way down to the bottom.

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

After that, when I scroll back up, all the cell heights change and the display gets all jumbled. Some text gets cut off, pictures get chopped and some of the cells only have the last portion of text. I really think it has something to do with reusing the cells, but I don’t know how to attack this problem. Below is my code for cellForRowAtIndexPath and 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 方法.

I even tried to make two different cells and call them separately, but the same thing happens. I did still use the same heightForRowAtIndexPath method.

- (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.)

The main problem is that you're adding subviews to cells every time they scroll in, but when a cell is reused, it will already have those subviews added. (That is, when a cell is reused, it will already have a UITextView or UIImageView depending on the reuse identifier.)

你需要先检查这些子视图是否存在;这通常通过使用 -[UIView viewWithTag] 方法,或者通过继承 UITableViewCell 并将每个视图分配为一个属性.

You need to check if these subviews exist first; this is commonly done by using the -[UIView viewWithTag] method, or by subclassing UITableViewCell and assigning each view as a property.

(你可以看看 SO 问题 How to get来自 UITableViewCell 的其他控件值? 以了解如何使用 viewWithTag.我会避免继承 UITableViewCell 直到您对开箱即用的实现更加满意.)

(You can take a look at the SO question How to get other control value from UITableViewCell? to see how to use viewWithTag. I would avoid subclassing UITableViewCell until you're more comfortable with the out-of-the-box implementation.)

还有这行代码:

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

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

is a terrible idea, because you are creating a new UITableViewCell without checking to see if you can reuse one first. This defeats the entire purpose of reusing cells, which is fast scrolling performance. Instead, just declare it without initializing it:

UITableViewCell *newCell;

此外,在 heightForRowAtIndexPath 中,您是

Also, in heightForRowAtIndexPath, you are

  • rowHeight 声明为 int(应该是 CGFloat)
  • 尝试在方法返回后调用 reloadData(这永远不会发生,但您永远不应该尝试从此方法调用 reloadData)
  • declaring rowHeight as an int (it should be a CGFloat)
  • trying to call reloadData after the method returns (which will never happen, but you should never try to call reloadData from this method)

这篇关于出列单元格的表视图问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆