ios UITableView cell.contentView.bounds.size.width 随 Cell Reuse 的变化

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6272009/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 20:15:21  来源:igfitidea点击:

UITableView cell.contentView.bounds.size.width Changes With Cell Reuse

iosuitableview

提问by BillEccles

I use cell.contentView.bounds.size.widthto calculate the position of a text field in a UITableView cell. When the cell is created, debug code reports the width as 302. When the cell scrolls off the screen and then back on, the debug code reports that the it is 280--every time. It doesn't seem to want to go back to 302 and stays stuck at 280. The net result is that the text field gets put in the wrong place the second time the field is put into the cell's contentView, though it was put in the right place the first time.

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

I figure 22 is significant somehow, but I don't know what it is. Guessing it might be the disclosure arrow, I moved the "clear the cell" code up front of the width determination, including setting the accessory to nada.

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

Can anybody tell me what's going on here?

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

The code (with irrelevant--that I know of--stuff snipped out) looks like this:

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

// 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;
}


Want to try this one at home, boys and girls?

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

Start with a new Navigation-based Application. Put the following code into RootViewController.m:

从一个新的基于导航的应用程序开始。将以下代码放入 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;
}

There are only two changes in the default code required to make this happen: changing the number of rows in the section ("return 5") and the style of the cell must be UITableViewCellStyleSubtitle. Then, when you run the program, you'll see five lines of this:

实现这一点所需的默认代码中只有两个更改:更改部分中的行数(“返回 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

Drag some cells off the screen (drag up--down doesn't do anything) and when they reappear, you get this:

将一些单元格从屏幕上拖出(向上-向下拖动不执行任何操作),当它们重新出现时,您会得到以下信息:

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

Frankly, I'm frustrated as heck with this, and am so very tempted to pony up the $99 (without a working app, even) so I can have somebody at Apple weigh in on this one.

坦率地说,我对此感到很沮丧,我非常想支付 99 美元(甚至没有可用的应用程序),这样我就可以让 Apple 的某个人参与进来。

Anybody got any ideas what's going on here?

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

Thanks!

谢谢!



Wanna' see something more interesting? Try this in place of the static NSString...line:

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

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

    NSLog(@"%@",CellIdentifier);

Now, every time, the width in the log is always302. It would seem, then, that a reused cell has different content width than the original cell.

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

Again... wondering... anybody got a clue?

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

回答by Jonah

I suspect that what you are seeing is due to changing the cell's accessory view which will eventually resize the content view the next time the cell performs -layoutSubviews. That should occur when the cell is added to the table but until then the bounds of the content view will not be updated.

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

Regardless I don't see why this would be an issue. You appear to only be concerned with setting the width of your theAgeTextFieldso if you size it appropriately relative to the content view's current width and set its autoresizingMaskflags to give it a flexible width then it should grow or shrink as needed when the bounds of the content view change.

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

If you need more detailed layout behavior then this should probably all occur within a UITableViewCellsubclass. See -prepareForReuseand -layoutSubviewsfor opportunities to customize the cell and its subviews. Your datasource should be able to just pass theAgeto an instance of your cell subclass and not be concerned with the details of how that will be displayed.

如果您需要更详细的布局行为,那么这可能都发生在UITableViewCell子类中。查看-prepareForReuse-layoutSubviews获取自定义单元格及其子视图的机会。您的数据源应该能够只传递theAge给您的单元格子类的一个实例,而不必关心如何显示的细节。

回答by jay492355

I ran into the same thing except that the offset was 20 instead of 22. I think Jonah's answer is on the right track, but for a quick workaround that avoids the resizing behavior of cell.contentView.frame/bounds I simply used cell.frame/bounds as my reference for laying out the views within the cell's contentView.

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

回答by Trausti Thor

You must implement height for row delegate method and do all your calculations in there

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

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

// do math

return newheight;
}

It will give you what you are after, you also have access to the index path, so you can easily find the row in your array and do everything you need, otherwise you will get the size of a reused row from the queue, which is always your default row size.

它会给你,你是什么之后,你还可以使用索引路径,所以你可以很容易地找到你的数组中的行,你需要的一切,否则你会从队列中,这是得到了重用行的大小始终是您的默认行大小。