2013-04-23 70 views
2

所以我有显示一个UITableView我的数据的麻烦。我相信这与重用单元格有关。我已经在网上查询过,但没有找到适合我的解决方案。任何帮助,将不胜感激。表视图的烦恼与离队细胞

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

任何想法?

回答

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)
+0

感谢您及时的回复!我会尝试这些事情并回复你。非常感谢您的时间! – Douglas 2013-04-23 17:16:11

+0

谢谢,如果您觉得有用,请将答案标记为已接受。 – 2013-04-23 18:40:13

+0

所以我试着看着你链接到的那篇文章。但他们似乎在方法cellForRowAtIndexPath之外创建子视图,标记它们,然后在方法中添加它们。但我在方法中创建了它们。我应该在哪里创造它们?因为我需要有关数组元素的信息来创建它们。根据你的建议,我也改变了一些事情。感谢那。 – Douglas 2013-04-23 21:51:28