UITableView cell.contentView.bounds.size.width使用单元重用进行更改

时间:2011-06-07 21:49:01

标签: ios uitableview

我使用cell.contentView.bounds.size.width来计算UITableView单元格中文本字段的位置。创建单元格时,调试代码将宽度报告为302.当单元格滚动屏幕然后重新打开时,调试代码每次都会报告它为280。它似乎不想回到302并且仍然停留在280.最终结果是文本字段在第二次将字段放入单元格的contentView时放入错误的位置,尽管它被放入第一次正确的地方。

我认为22在某种程度上是重要的,但我不知道它是什么。猜测它可能是披露箭头,我在宽度测定前移动了“清除单元格”代码,包括将附件设置为虚无..。

有谁能告诉我这里发生了什么?

代码(无关紧要 - 我知道 - 东西被剪掉了)看起来像这样:

// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    static NSString *CellIdentifier = @"Cell";

    NSUInteger section = [indexPath section];
    NSUInteger row = [indexPath row];

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
    }


    // Configure the cell.

    while( [cell.contentView.subviews count] ){
        id subview = [cell.contentView.subviews objectAtIndex:0];
        [subview removeFromSuperview];  
    }
    cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;

8< snip!

    CGFloat theCellWidth = cell.contentView.bounds.size.width - 44.0;
    CGFloat theLineHeight = [[UIFont boldSystemFontOfSize: [UIFont labelFontSize]+1.0] lineHeight]; 

    NSLog(@"cell.contentView.bounds.size.width %1.0f",cell.contentView.bounds.size.width);

    if (0==section) {
        switch (row) {
            case 2:
                while( [cell.contentView.subviews count] ){
                    id subview = [cell.contentView.subviews objectAtIndex:0];
                    [subview removeFromSuperview];  
                }
                cell.selectionStyle = UITableViewCellSelectionStyleNone;
                cell.textLabel.text = @" ";
                cell.detailTextLabel.text = @"The Age";
                theAgeTextField.frame = CGRectMake(10.0, 2.0, theCellWidth, theLineHeight);
//                NSLog(@"cell.contentView %@",cell.contentView);
                theAgeTextField.text = theAge;
                theAgeTextField.font = [UIFont boldSystemFontOfSize: [UIFont labelFontSize]+1.0];
                theAgeTextField.keyboardType = UIKeyboardTypeDecimalPad;
                theAgeTextField.borderStyle = UITextBorderStyleNone;
                theAgeTextField.userInteractionEnabled = NO;
                [cell.contentView addSubview:theAgeTextField];
                cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
                break;

8< snip! (lots of closing braces and other stuff omitted)

    return cell;
}

想在家里试试这个,男孩和女孩吗?

从新的基于导航的应用程序开始。将以下代码放入RootViewController.m:

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return 5;
}

// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"Cell";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
    }

    NSLog(@"cell.contentView.bounds.size.width %1.0f",cell.contentView.bounds.size.width);
    // Configure the cell.
    return cell;
}

实现此目的所需的默认代码只有两处更改:更改部分中的行数(“返回5”),单元格的样式必须为 UITableViewCellStyleSubtitle 。然后,当你运行程序时,你会看到五行:

2011-06-18 11:10:19.976 TestTableCells[7569:207] cell.contentView.bounds.size.width 302
2011-06-18 11:10:19.978 TestTableCells[7569:207] cell.contentView.bounds.size.width 302
2011-06-18 11:10:19.979 TestTableCells[7569:207] cell.contentView.bounds.size.width 302
2011-06-18 11:10:19.980 TestTableCells[7569:207] cell.contentView.bounds.size.width 302
2011-06-18 11:10:19.982 TestTableCells[7569:207] cell.contentView.bounds.size.width 302

将一些细胞拖出屏幕(向上 - 向下拖动不做任何事情),当它们重新出现时,你会得到这个:

2011-06-18 11:10:24.013 TestTableCells[7569:207] cell.contentView.bounds.size.width 320
2011-06-18 11:10:24.047 TestTableCells[7569:207] cell.contentView.bounds.size.width 320
2011-06-18 11:10:24.130 TestTableCells[7569:207] cell.contentView.bounds.size.width 320

坦率地说,我很沮丧,因为我非常想要花99美元(甚至没有工作的应用程序),所以我可以让苹果公司的人在这一点上权衡。

有人知道这里发生了什么吗?

谢谢!


想要看到更有趣的东西吗?试试这个代替static NSString...行:

    NSString *CellIdentifier = [NSString stringWithFormat: @"%d", arc4random() ];

    NSLog(@"%@",CellIdentifier);

现在,每次日志中的宽度总是 302.那么,重复使用的单元格的内容宽度似乎与原始单元格不同。

再次......想知道......有人知道吗?

3 个答案:

答案 0 :(得分:10)

我怀疑你所看到的是由于更改了单元格的附件视图,最终会在单元格下次执行-layoutSubviews时调整内容视图的大小。将单元格添加到表格时会发生这种情况,但在此之前内容视图的边界将不会更新。

无论如何我不明白为什么这会是一个问题。您似乎只关心设置theAgeTextField的宽度,所以如果相对于内容视图的当前宽度适当调整大小并设置其autoresizingMask标志以使其具有灵活的宽度,那么它应该增长或者当内容视图的边界发生变化时,根据需要缩小。

如果您需要更详细的布局行为,那么这可能都发生在UITableViewCell子类中。有关自定义单元格及其子视图的机会,请参阅-prepareForReuse-layoutSubviews。您的数据源应该只能将theAge传递给您的单元子类的实例,而不关心将如何显示它的详细信息。

答案 1 :(得分:1)

我遇到了同样的事情,除了偏移是20而不是22.我认为Jonah的答案是在正确的轨道上,但是为了避免cell.contentView.frame / bounds的调整行为的快速解决方法我只是使用cell.frame / bounds作为我在单元格contentView中布局视图的参考。

答案 2 :(得分:0)

您必须为行委托方法实现高度,并在那里进行所有计算

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {

// do math

return newheight;
}

它将为您提供所需的内容,您还可以访问索引路径,这样您就可以轻松找到数组中的行并执行所需的一切,否则您将从队列中获得重用行的大小,这始终是您的默认行大小。