4

我在屏幕上添加了一个简单的 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;
}

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

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

谢谢!

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

4

3 回答 3

2

问题是细胞被回收了。想想看。每次初始化或重用单元格时,您已将所有这些 UIView 附加到单元格。简单地移动括号将导致仅在初始化时附加视图。

- (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 并创建您自己的自定义类,让您设置视图的唯一值。

于 2013-02-24T09:49:29.987 回答
2

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

于 2013-02-24T09:15:44.153 回答
2

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

正确的方法是将其子类化并将添加的视图作为属性公开。

错误的方法是像这样修改您的代码:

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

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

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

当你决定子类化时,不要忘记实施:

- (NSString *)reuseIdentifier
{
  return @"hereGoesTeuseIdentifierThatYouWillUseForThissKindOfCell";
}
于 2013-02-24T09:26:58.410 回答