带有子视图的UITableViewCell不会被重用

时间:2013-02-24 09:13:51

标签: iphone ios uitableview

我在屏幕上添加了一个简单的UITableView。但是,我希望其中的单元格显示一堆自定义UI元素(主要是视图和标签)。由于UITableViewCell没有给我很多机会自由地定制它,我决定添加我需要的所有元素作为单元格的子视图。这是我的cellForRowAtIndexPath方法:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

if (cell == nil)
{
    cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
                                  reuseIdentifier:CellIdentifier];
}

UIView *view1 = [[UIView alloc] initWithFrame:CGRectMake(10.0f, 10.0f, 25.0f, 25.0f)];
view1.backgroundColor = [UIColor redColor];
view1.layer.shadowColor = [[UIColor blackColor] CGColor];
view1.layer.shadowOffset = CGSizeMake(0.0f, 0.0f);
view1.layer.shadowOpacity = 0.8f;
view1.layer.shadowRadius = 3.0f;
[cell addSubview:view1];

UILabel *label1 = [[UILabel alloc] initWithFrame:CGRectMake(85.0f, 5.0f, 100.0f, 15.0f)];
label1.text = @"dummy text 1";
label1.backgroundColor = [UIColor clearColor];
label1.textColor = [UIColor lightGrayColor];
label1.textAlignment = UITextAlignmentRight;
label1.font = [UIFont systemFontOfSize:12.0f];
label1.lineBreakMode = NSLineBreakByTruncatingTail;
label1.shadowOffset = CGSizeMake(0.0f, 1.0f);
label1.shadowColor = [UIColor blackColor];
[cell addSubview:label1];

UILabel *label2 = [[UILabel alloc] initWithFrame:CGRectMake(85.0f, 25.0f, 100.0f, 15.0f)];
label2.text = @"dummy text 2";
label2.backgroundColor = [UIColor clearColor];
label2.textColor = [UIColor lightGrayColor];
label2.textAlignment = UITextAlignmentRight;
label2.font = [UIFont systemFontOfSize:12.0f];
label2.lineBreakMode = NSLineBreakByTruncatingTail;
label2.shadowOffset = CGSizeMake(0.0f, 1.0f);
label2.shadowColor = [UIColor blackColor];
[cell addSubview:label2];

UILabel *label3 = [[UILabel alloc] initWithFrame:CGRectMake(85.0f, 45.0f, 100.0f, 15.0f)];
label3.text = @"dummy text 3";
label3.backgroundColor = [UIColor clearColor];
label3.textColor = [UIColor lightGrayColor];
label3.textAlignment = UITextAlignmentRight;
label3.font = [UIFont systemFontOfSize:12.0f];
label3.lineBreakMode = NSLineBreakByTruncatingTail;
label3.shadowOffset = CGSizeMake(0.0f, 1.0f);
label3.shadowColor = [UIColor blackColor];
[cell addSubview:label3];

return cell;
}

就细胞定制而言,上述所有代码都能正常工作。问题是,当一个单元格离开可见区域时,其子视图不会被释放。当我上下移动桌面视图时,添加的UIView上的阴影变得越来越暗,我猜测标签也没有被释放。

如何解决此问题?我想我可以继承一个UITableViewCell类,但我只是在一个单元格的类中添加子视图。它似乎不是一个解决方案。有没有办法让细胞在消失时释放其子视图,或者是真正自由地定制细胞的可靠方法?

谢谢!

一些额外的信息: 我不使用IB(以编程方式执行所有操作) 我用ARC 我使用Xcode 4.6 我的SDK是iOS 6.1

3 个答案:

答案 0 :(得分:2)

您应该创建一个UITableViewCell子类并在那里进行所有自定义。

答案 1 :(得分:2)

您可以通过两种方式使代码工作。

正确方式继承方式并将添加的视图公开为属性。

错误的方式是修改你的代码:

if (cell == nil)
{
    cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
                                  reuseIdentifier:CellIdentifier];
}

for (UIView *cellView in sell.view)
{
    [cellView removeFromSuperVuew];
}

你注意到自己阴影变得越来越暗。这是因为每次加载(而不仅仅是在创建时)都会添加(在所有其他子视图中)您的单元格。

当你决定子类时不要忘记imlement:

- (NSString *)reuseIdentifier
{
  return @"hereGoesTeuseIdentifierThatYouWillUseForThissKindOfCell";
}

答案 2 :(得分:2)

问题在于细胞被回收利用。想一想。每次初始化或重用单元格时,您都已将所有这些UIViews附加到单元格中。简单地移动paren将导致仅在初始化时附加视图。

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"Cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

    if (cell == nil)
    {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
                                       reuseIdentifier:CellIdentifier];

        UIView *view1 = [[UIView alloc] initWithFrame:CGRectMake(10.0f, 10.0f, 25.0f, 25.0f)];
        view1.backgroundColor = [UIColor redColor];
        view1.layer.shadowColor = [[UIColor blackColor] CGColor];
        view1.layer.shadowOffset = CGSizeMake(0.0f, 0.0f);
        view1.layer.shadowOpacity = 0.8f;
        view1.layer.shadowRadius = 3.0f;
        [cell addSubview:view1];

        UILabel *label1 = [[UILabel alloc] initWithFrame:CGRectMake(85.0f, 5.0f, 100.0f, 15.0f)];
        label1.text = @"dummy text 1";
        label1.backgroundColor = [UIColor clearColor];
        label1.textColor = [UIColor lightGrayColor];
        label1.textAlignment = UITextAlignmentRight;
        label1.font = [UIFont systemFontOfSize:12.0f];
        label1.lineBreakMode = NSLineBreakByTruncatingTail;
        label1.shadowOffset = CGSizeMake(0.0f, 1.0f);
        label1.shadowColor = [UIColor blackColor];
        [cell addSubview:label1];

        UILabel *label2 = [[UILabel alloc] initWithFrame:CGRectMake(85.0f, 25.0f, 100.0f, 15.0f)];
        label2.text = @"dummy text 2";
        label2.backgroundColor = [UIColor clearColor];
        label2.textColor = [UIColor lightGrayColor];
        label2.textAlignment = UITextAlignmentRight;
        label2.font = [UIFont systemFontOfSize:12.0f];
        label2.lineBreakMode = NSLineBreakByTruncatingTail;
        label2.shadowOffset = CGSizeMake(0.0f, 1.0f);
        label2.shadowColor = [UIColor blackColor];
        [cell addSubview:label2];

        UILabel *label3 = [[UILabel alloc] initWithFrame:CGRectMake(85.0f, 45.0f, 100.0f, 15.0f)];
        label3.text = @"dummy text 3";
        label3.backgroundColor = [UIColor clearColor];
        label3.textColor = [UIColor lightGrayColor];
        label3.textAlignment = UITextAlignmentRight;
        label3.font = [UIFont systemFontOfSize:12.0f];
        label3.lineBreakMode = NSLineBreakByTruncatingTail;
        label3.shadowOffset = CGSizeMake(0.0f, 1.0f);
        label3.shadowColor = [UIColor blackColor];
        [cell addSubview:label3];
    }

    return cell;
}

那就是说...如果你想通过添加内容来使这些细胞变得有趣,你需要每次从细胞中移除它们或者保持对细胞子视图的引用。最后一点,如果你能提供帮助,请不要删除所有视图。如果值只是更改,则继承UITableViewCell并创建自己的自定义类,让您设置视图的唯一值。