0

我有一个似乎无法解决的特别问题我已经查看了我的代码几个小时,但似乎无法解决问题。

当我将消息添加到我的表格视图时,消息会溢出 UITableViewCell 中的包装器,有时包装器会被单元格截断。

我如何确保我的包装器总是足够大以容纳 txt (lblMessage) 并且单元格足够大以容纳包装器。

提前致谢 !

-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    CGFloat height = [self heightForMessage:indexPath];

    if(height < 50)
    {
        NSLog(@"Normal : %d , row : %d", 100,indexPath.row);
        return 100;
    }    
    else
    {
        NSLog(@"Custom : %f , row : %d", 70 + height,indexPath.row);
        return 70 + height;
    }
}

-(CGFloat)heightForMessage:(NSIndexPath *)indexPath
{
    MessageObject * model = [self.chats objectAtIndex:indexPath.row];

    CGSize size = [model.message sizeWithFont:[UIFont fontWithName:@"HelveticaNeue-Light" size:12] constrainedToSize:CGSizeMake(290, 100000) lineBreakMode:NSLineBreakByWordWrapping];

    return size.height;
}

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString * NewsCellIdentifer = @"NewsCellIdentifier";
    UITableViewCell * cell = [tableView dequeueReusableCellWithIdentifier:NewsCellIdentifer];

    UILabel * lblContact;
    UILabel * lblMessage;
    UILabel * lblDate;
    UIView * wrapper;

    if (cell == nil)
    {

        /* Top menu for login */

        wrapper = [[UIView alloc] initWithFrame:CGRectMake(10, 5, 300, 90)];
        [wrapper setBackgroundColor:[self.delegate.color colorWithAlphaComponent:0.6f]];
        [wrapper.layer setCornerRadius:6.0f];
        [wrapper.layer setShadowOffset:CGSizeMake(0, 2)];
        [wrapper.layer setShadowRadius:2.0f];
        [wrapper.layer setShadowOpacity:0.5f];
        [wrapper viewWithTag:19];
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:NewsCellIdentifer];

        /* Contact Name */

        lblContact = [[UILabel alloc] initWithFrame:CGRectMake(10, 0, 150, 30)];
        [lblContact setFont:[UIFont fontWithName:@"HelveticaNeue-Medium" size:13]];
        [lblContact setTag:13];
        [lblContact setTextColor:[self.delegate colorFromHexString:@"#fffbff"]];
        [lblContact setBackgroundColor:[UIColor clearColor]];

        /* Received Message */

        lblMessage = [[UILabel alloc] initWithFrame:CGRectMake(10, 20, 280, 50)];
        [lblMessage setNumberOfLines:0];
        [lblMessage setLineBreakMode:NSLineBreakByWordWrapping];
        [lblMessage setBackgroundColor:[UIColor clearColor]];
        [lblMessage setFont:[UIFont fontWithName:@"HelveticaNeue-Light" size:12]];
        [lblMessage setTextColor:[self.delegate colorFromHexString:@"#fffbff"]];
        [lblMessage setTag:14];


        /* Date received */

        lblDate = [[UILabel alloc] initWithFrame:CGRectMake(10, 65, 65, 30)];
        [lblDate setText:@"4 hours ago"];
        [lblDate setFont:[UIFont fontWithName:@"HelveticaNeue-Light" size:11]];
        [lblDate setTextColor:[self.delegate colorFromHexString:@"#fffbff"]];
        [lblDate setTag:15];

        /* Subview Logic */

        [wrapper addSubview:lblContact];
        [wrapper addSubview:lblMessage];
        [wrapper addSubview:lblDate];

        [cell setSelectionStyle:UITableViewCellSelectionStyleNone];
        [cell.contentView addSubview:wrapper];
    }
    else
    {
        lblContact = (UILabel *)[cell.contentView viewWithTag:13];
        lblMessage = (UILabel *)[cell.contentView viewWithTag:14];
        wrapper = [cell.contentView viewWithTag:19];
    }

    MessageObject * model = [self.chats objectAtIndex:indexPath.row];

    CGFloat height = [self heightForMessage:indexPath];

    [lblMessage setFrame:CGRectMake(10, 25, 280, height)];
    [lblMessage setText:model.message];

    [lblContact setText:model.clientModel.firstName];

    if(height < 50)
    {
        NSLog(@"wrapper size : %d for row %d ", 90, indexPath.row);
        [wrapper setFrame:CGRectMake(10, 5, 300, 90)];
    }
    else
    {
        NSLog(@"wrapper size : %f for row %d ", height + 60, indexPath.row);

        [wrapper setFrame:CGRectMake(10, 5, 300, height + 60)];
        [lblDate setFrame:CGRectMake(10, height + 20, 65, 30)];
    }

    [cell.contentView setBackgroundColor:[UIColor greenColor]];
    [cell setBackgroundColor:[UIColor clearColor]];

    return cell;
 }
4

6 回答 6

2

考虑显着改进您的代码...因为它现在几乎不可读
1) 摆脱硬编码,例如 20、280。而是考虑使用常量 (CONTACT_LABEL_TO_MESSAGE_LABEL_OFFSET, MESSAGE_LABEL_WIDTH)
2) 摆脱将自定义子视图添加到 UITableViewCell 并用硬编码标记它们(参见1) 数字 - 取而代之的是 UITableViewCell 的子类,在 .xib 或 .storyboard 中对其进行原型设计,为您的类创建方便的方法 - 例如 setDate:、setMessage:、setContactName:。所有帧都应在您的子类 -layoutSubviews 方法中计算。

乍一看:
1)您将280的宽度设置为lblMessage,当您将其文本限制为290的宽度时,会导致错误的高度计算

于 2013-09-24T15:30:58.603 回答
1

我建议使用原型单元并通过使用给定索引路径的数据配置原型来计算单元高度。只需将一个单元格出列(是的,您可以在 之外执行此操作cellForRowAtIndexPath)并按住它进行高度计算。对于动态高度标签,您通常会调用[label sizeToFit]单元格的配置逻辑。在这个问题中对此技术有更详细的讨论。

如果您想查看第 3 方库,我的TLIndexPathTools库提供了一个基表视图类,该类TLTableViewController使用原型内置支持动态行高:

  1. 对于静态的、非数据驱动的高度,它将返回原型的默认高度。因此,如果您的原型来自 Storyboard,它将遵循 Storyboard 自定义单元格高度。
  2. 对于动态的、数据驱动的高度,任何实现TLDynamicHeightView协议的自定义单元格都将自动计算动态高度。
于 2013-09-24T15:53:19.613 回答
1

错误之一是当您为新单元格创建包装器视图时:

[wrapper viewWithTag:19];

应该:

[wrapper setTag:19];

当您尝试在重用单元格上调整它的大小时,这可能会导致wrapper为零。

于 2013-09-24T15:58:32.473 回答
1

我会告诉你我用来解决这个问题的方法。

  • 用于array存储高度(使用sizeWithFont)。它现在已被弃用,因此您应该尝试使用它sizeWithAttributes
  • 记录 的高度array和实际标签的高度,看看它们是否匹配。
  • 确保UIFontusedsizeWithFont和 yourLabel.font 中的 used 相同。
  • 检查您是否在单元格中进行了任何类型的填充,例如在单元格顶部留下像素。

这些是一般提示。

于 2013-09-24T16:17:06.703 回答
0

要计算标签高度,您应该考虑不同的事情,您必须通过记住文本长度及其字体以及要添加的框架的边界来计算大小。下面是如何计算动态文本大小的示例。

CGSize boundingSize = CGSizeMake(frame.size.width, CGFLOAT_MAX);
    CGSize requiredSize = [text sizeWithFont:yourFont constrainedToSize:boundingSize lineBreakMode:NSLineBreakByWordWrapping];
于 2013-09-24T15:40:38.343 回答
0

当您在其中创建一个单元格时,tableView: cellForRowAtIndexPath:您可以将其存储到一个NSMutableArray
Then中,然后tableView: heightForRowAtIndexPath:只需检索该单元格并指定它的高度。

我大部分时间都是这样做的,但是如果您使用大量单元格,它可能会占用大量内存。或者,也许您只能将单元格的大小存储在 NSMutableArray 中。


编辑:

我不确定我是否理解正确。
您希望您的单元格能够包含您的包装器吗?

cell.contentView.frame = CGRectMake(0, 0, cell.contentView.frame.size.width, wrapper.frame.origin.y + wrapper.frame.size.height);

将单元格存储在 NSMutableArray 中tableView: cellForRowAtIndexPath:,根据它的索引检索它tableView: heightForRowAtIndexPath:

于 2013-09-24T15:22:46.867 回答