UITableViewCell 高度与 UILabel 和随机文本长度的问题

发布于 11-30 15:16 字数 2070 浏览 1 评论 0原文

我目前正在尝试让 UITableView 使用基于数组中文本的自定义单元格高度。我看到的问题是文本似乎在某个点上挤在一起,而不是填充自定义单元格的整个长度。这会导致文本在单元格上重叠,有时会在单元格下消失。

这是我用于确定单元格高度的代码,我不确定标准 UILabel 文本高度,但这似乎在字体高度下效果很好。

if (indexPath.section == 0) {

    NSString *text = [[self.recipeDict objectForKey:@"Ingredients"] objectAtIndex:[indexPath row]];

    CGSize constraint = CGSizeMake(320 - (10 * 2), 20000.0f);

    CGSize size = [text sizeWithFont:[UIFont systemFontOfSize:12] constrainedToSize:constraint lineBreakMode:UILineBreakModeWordWrap];

    CGFloat height = size.height;

    return height + 20;
}

另外,以防万一细胞的创建阻碍了我的问题,或者只是帮助您了解发生了什么,这也是如此。

UITableViewCell *cell;
UITableViewCell *ingredientCell;
UITableViewCell *methodCell;

if (indexPath.section == 0) {
    UILabel *ingredientText;

    static NSString *ingredientCellIdentifier = @"Ingredient Cell";

    ingredientCell = [tableView dequeueReusableCellWithIdentifier: ingredientCellIdentifier];

    if (ingredientCell == nil)
    {
        ingredientCell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier: ingredientCellIdentifier] autorelease];

        ingredientText = [[UILabel alloc] initWithFrame:CGRectMake(15, 7, 290, 44)];
        [ingredientText setLineBreakMode:UILineBreakModeWordWrap];
        [ingredientText setNumberOfLines:0];
        [ingredientCell.contentView addSubview:ingredientText];

        ingredientText.tag = 1;

        [ingredientText release];

        ingredientCell.contentMode = UIViewContentModeRedraw;
    }

    ingredientText = (UILabel*)[ingredientCell viewWithTag:1];
    ingredientText.text = [[self.recipeDict objectForKey:@"Ingredients"] objectAtIndex: indexPath.row];
    [ingredientText sizeToFit];

    return ingredientCell;
}

这是我第二次尝试解决这个问题,但这似乎超出了我目前的能力,所以我欢迎通过经验获得的智慧。

更新 -

经过进一步调查,似乎是调整 UILabel 成分文本大小导致了该问题。

它一开始的高度与显示的文本所需的高度相同,但是当该标签为另一段需要更多行的文本以更大的高度重新绘制时,它永远不会再缩小。看起来 sizeToFit 方法是优先使用可用高度,而不是占用宽度并缩小高度。

现在,我在 sizeToFit 之后再次设置了宽度,这解决了该问题,但根据标签的高度,它会导致奇怪的间距。

I'm currently trying to get a UITableView to use custom cell heights based on text in an array. The problem I'm seeing is that the text seems to squish together at point rather than filling the full length of a custom cell. This results in the text overlapping over cells, sometimes disappearing under them.

Here's the code I have for determining the cell height, I'm not sure of the standard UILabel text height but this seemed to work well at the height I for the font.

if (indexPath.section == 0) {

    NSString *text = [[self.recipeDict objectForKey:@"Ingredients"] objectAtIndex:[indexPath row]];

    CGSize constraint = CGSizeMake(320 - (10 * 2), 20000.0f);

    CGSize size = [text sizeWithFont:[UIFont systemFontOfSize:12] constrainedToSize:constraint lineBreakMode:UILineBreakModeWordWrap];

    CGFloat height = size.height;

    return height + 20;
}

Also just in case the creation of the cells is either a hinderance to my problem or just helps you know what's going on, here's that too.

UITableViewCell *cell;
UITableViewCell *ingredientCell;
UITableViewCell *methodCell;

if (indexPath.section == 0) {
    UILabel *ingredientText;

    static NSString *ingredientCellIdentifier = @"Ingredient Cell";

    ingredientCell = [tableView dequeueReusableCellWithIdentifier: ingredientCellIdentifier];

    if (ingredientCell == nil)
    {
        ingredientCell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier: ingredientCellIdentifier] autorelease];

        ingredientText = [[UILabel alloc] initWithFrame:CGRectMake(15, 7, 290, 44)];
        [ingredientText setLineBreakMode:UILineBreakModeWordWrap];
        [ingredientText setNumberOfLines:0];
        [ingredientCell.contentView addSubview:ingredientText];

        ingredientText.tag = 1;

        [ingredientText release];

        ingredientCell.contentMode = UIViewContentModeRedraw;
    }

    ingredientText = (UILabel*)[ingredientCell viewWithTag:1];
    ingredientText.text = [[self.recipeDict objectForKey:@"Ingredients"] objectAtIndex: indexPath.row];
    [ingredientText sizeToFit];

    return ingredientCell;
}

This is my second attempt at solving this issue but it seems to be beyond my current ability so I welcome wisdom gained through experience.

UPDATE -

After further investigation it seems that the UILabel ingredientText being resized is causing the issue.

It starts out as tall as it needs to be for the text shown, however when that label is redrawn with a larger height for another piece of text which requires more lines it's never shrunk down again. It seems that the sizeToFit method is prioritising using the available height rather than taking up the width and shrinking the height.

Right now I've set the width again after the sizeToFit which works around the issue but it leads to odd spacing depending on the height of the label.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

黎歌2024-12-07 15:16:16

有几件事:

  • 您还没有设置 UILabel 的字体,这意味着您的大小调整到未知的高度
  • 您需要设置 UILabel 自动调整大小蒙版,以便它在单元格高度变化时调整大小

这是工作代码(已测试) :

-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
    if (indexPath.section == 0) {

        NSString *text = [_items objectAtIndex:[indexPath row]];

        CGSize constraint = CGSizeMake(320 - (10 * 2), 20000.0f);

        CGSize size = [text sizeWithFont:[UIFont systemFontOfSize:12] constrainedToSize:constraint lineBreakMode:UILineBreakModeWordWrap];

        CGFloat height = size.height;

        return height + 20;
    }

    return tableView.rowHeight;
}

#pragma mark - UITableViewDatasource

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    UITableViewCell *cell;
    UITableViewCell *ingredientCell = nil;
    UITableViewCell *methodCell;

    if (indexPath.section == 0) {
        UILabel *ingredientText;

        static NSString *ingredientCellIdentifier = @"Ingredient Cell";

        ingredientCell = [tableView dequeueReusableCellWithIdentifier: ingredientCellIdentifier];

        if (ingredientCell == nil)
        {
            ingredientCell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier: ingredientCellIdentifier] autorelease];

            ingredientText = [[UILabel alloc] initWithFrame:ingredientCell.bounds];
            ingredientText.font = [UIFont systemFontOfSize:12.0f];
            ingredientText.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
            [ingredientText setLineBreakMode:UILineBreakModeWordWrap];
            [ingredientText setNumberOfLines:0];
            [ingredientCell.contentView addSubview:ingredientText];

            ingredientText.tag = 1;

            [ingredientText release];

            ingredientCell.contentMode = UIViewContentModeRedraw;
        }

        ingredientText = (UILabel*)[ingredientCell viewWithTag:1];
        ingredientText.text = [_items objectAtIndex: indexPath.row];

        return ingredientCell; 
    }

}
  • 确保始终返回 tableView:cellForRowAtIndexPath: 和 tableView:heightForRowAtIndexPath: 方法的值

A couple of things:

  • You have not set the font for the UILabel, which means you're sizing to an unknown height
  • You need to set your UILabel autoresizing mask, so that it sizes when the cell height changes

Here is working code (tested):

-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
    if (indexPath.section == 0) {

        NSString *text = [_items objectAtIndex:[indexPath row]];

        CGSize constraint = CGSizeMake(320 - (10 * 2), 20000.0f);

        CGSize size = [text sizeWithFont:[UIFont systemFontOfSize:12] constrainedToSize:constraint lineBreakMode:UILineBreakModeWordWrap];

        CGFloat height = size.height;

        return height + 20;
    }

    return tableView.rowHeight;
}

#pragma mark - UITableViewDatasource

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    UITableViewCell *cell;
    UITableViewCell *ingredientCell = nil;
    UITableViewCell *methodCell;

    if (indexPath.section == 0) {
        UILabel *ingredientText;

        static NSString *ingredientCellIdentifier = @"Ingredient Cell";

        ingredientCell = [tableView dequeueReusableCellWithIdentifier: ingredientCellIdentifier];

        if (ingredientCell == nil)
        {
            ingredientCell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier: ingredientCellIdentifier] autorelease];

            ingredientText = [[UILabel alloc] initWithFrame:ingredientCell.bounds];
            ingredientText.font = [UIFont systemFontOfSize:12.0f];
            ingredientText.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
            [ingredientText setLineBreakMode:UILineBreakModeWordWrap];
            [ingredientText setNumberOfLines:0];
            [ingredientCell.contentView addSubview:ingredientText];

            ingredientText.tag = 1;

            [ingredientText release];

            ingredientCell.contentMode = UIViewContentModeRedraw;
        }

        ingredientText = (UILabel*)[ingredientCell viewWithTag:1];
        ingredientText.text = [_items objectAtIndex: indexPath.row];

        return ingredientCell; 
    }

}
  • Be sure you are always be returning a values for tableView:cellForRowAtIndexPath: and tableView:heightForRowAtIndexPath: methods
鲜肉鲜肉永远不皱2024-12-07 15:16:16

此问题的解决方案是单元格高度方法中的常量中指定的宽度与稍后在 cellForRowAtIndexPath 方法中指定的单元格文本的框架不匹配。

一旦这些相同,问题就会自行解决。

不同的常量大小导致报告的 UILabel 高度不一致且不准确。这导致设置了不正确的表格行高。

The solution to this issue was that the width specified in the constant in the cell height method didn't match the frame for the cell text specified later in the cellForRowAtIndexPath method.

Once these are the same the problem resolves itself.

The different constant size led to inconsistent and inaccurate UILabel heights being reported. This led to incorrect table row heights being set.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文