可以在UITableViewCells中使用视图控制器的xib中定义的UITextField吗?

时间:2012-03-27 22:12:55

标签: ios uitableview

我正在尝试做一些我认为相当简单且完全可以接受的事情。除此之外,它似乎都不是。

我创建了一个XIB,其所有者是一个视图控制器。在那个XIB中,我创建了多个UITextField,并将它们连接到视图控制器中的相应IBOutlet。视图控制器也是UITableView的委托,它包含在控制器的主视图中。

tableView:cellForRowAtIndexPath:然后我按照你的期望创建一个UITableViewCell(重用标识符等)。然后我将相应的IBOutletted UITextField(取决于当前行)添加到UITableViewCell的contentView(首先在UITextField上调用removeFromSuperview之后)。

这在视图最初加载时工作正常。但是,一旦我开始执行导致UITableView重新加载其数据的操作,UITextFields就会发生奇怪的事情。也就是说,他们中的大多数开始从桌面视图中消失,而其他人则在宽度上急剧缩小。

那么,我在做一些我不该做的事情吗?您可以猜测,在IB中配置这些UITextField非常有用,除非它似乎是错误的方法。

来自tableView的代码snippit:cellForRowAtIndexPath:below ...

- (UITableViewCell *)tableView:(UITableView *)aTableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = nil;
int row = indexPath.row;

if (indexPath.section == kSectionReg) {
    NSString *reuseIdent = @"RegCell";
    cell = [aTableView dequeueReusableCellWithIdentifier:reuseIdent];
    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue2 reuseIdentifier:reuseIdent] autorelease];
    }
    cell.detailTextLabel.font = [UIFont systemFontOfSize:15];
    cell.detailTextLabel.backgroundColor = [UIColor clearColor];


    if (row == [self rowIndexForRegEmail]) {
        [regEmailText removeFromSuperview];
        [cell.contentView addSubview:regEmailText];
        cell.detailTextLabel.text = @"Email";
    } else if (row == [self rowIndexForRegPassword]) {
        [regPasswordText removeFromSuperview];
        [cell.contentView addSubview:regPasswordText];
        cell.detailTextLabel.text = @"Password";
    ... etc...
    }

    return cell;
}

2 个答案:

答案 0 :(得分:1)

我不是百分百肯定,但我认为这是你的问题:

    [regEmailText removeFromSuperview];
    [cell.contentView addSubview:regEmailText];

内存管理隐含在视图层次结构中:视图拥有(保留)其子视图。从超级视图中删除视图时,它会被释放,如果没有其他内容保留它,它将被取消分配。

每当表格视图要求一个单元格时,你就会这样做,而不仅仅是在第一次创建单元格的时候:在第一次传递时,当你调用removeFromSuperview时,文本字段仍被某些东西引用(1) ,所以它仍然在下一行,你可以将它添加到单元格。在随后的通话中,没有其他保留文本字段;当你从单元格中删除它时它会被释放,所以它会在你重新添加它的下一行中消失 - 这就是它消失的原因。(2)

最直接的解决方法是确保文本字段不会消失 - 将其粘贴在保留/强大的ivar或属性中(或仅retain之前removeFromSuperview和{{1} release之后,如果你没有使用ARC)。另一种选择可能是为具有唯一文本字段的每个单元使用不同的可重用单元标识符。

更一般地说,您可能需要考虑Apple的technique for static row content。甚至更好:如果您使用的是iOS 5,则可以使用故事板在IB中完全执行静态表。


(1)(2):最初是什么引用它,以及为什么某些字段调整大小,不那么简单,部分取决于你问题中未显示的内容。我现在必须跑 - 我的答案的其余部分应该可以解决你的问题,我将编辑这个答案,详细说明以后进一步启发。

答案 1 :(得分:1)

这将彻底崩溃。 (我猜你已经告诉我们了)

我假设您将此视为“静态表视图” - 即具有相同类型数据的相同数量的单元格将在那里。

问题是如果任何单元格被滚动出视图,它们将被重用,因为它们都被重新识别为@“RegCell”。

除此之外:你需要removeFromSuperview,当你添加到子视图时,重新显示会很好。

您只想构建一次视图层次结构。它们看起来很相似,但如果它们不同,则使用不同的重用标识符。如果它们是相同的,则只在第一次构建它们(在if (cell == nil)内。