【问题标题】:Incorrect text wrapping in a UITableViewCellUITableViewCell 中的文本换行不正确
【发布时间】:2013-04-26 04:26:46
【问题描述】:

我的自定义 UITableView 出现问题。我想知道如何正确地将一组文本放入单元格中而不会看到任何省略号“...”并且文本不会在单元格末尾被截断。

这是我的细胞目前的样子:

它是UISplitViewController 的一部分。这样做的问题是,之前由于某种原因它会显示文本的整个长度,但它会到达单元格的末尾并且字符串的其余部分被切断(当我检查“AutoLayout”时会发生这种情况)。

这是我的代码目前的样子:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"BCell";

    BracketTableCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

    if(cell == nil)
    {
        cell = [[BracketTableCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
        [cell.description setLineBreakMode:NSLineBreakByWordWrapping];
        cell.description.numberOfLines = 0;
        cell.description.font = [UIFont fontWithName:@"Helvetica" size:14.0];
    }

    Bracket *bracket = [brackets objectAtIndex:indexPath.row];

    [cell.description setText:bracket.name];
    [cell.bracketId setText:[NSString stringWithFormat:@"%@", bracket.bracketId]];    

    return cell;
}

我正在尝试高度,但这似乎无关紧要,因为我可以将高度设置为任意值,但它仍然显示截断的文本。

谢谢!

【问题讨论】:

  • 您打算使用 AutoLayout 吗?我知道你说你打开它并导致问题,但我不确定这是否是一个调试步骤,或者你是否希望它总是打开。你能把BracketTableCell的代码贴出来吗?
  • 我在 BracketTableCell 上没有任何代码。它是一个自定义表格单元类,具有描述和图标的属性。就是这样。没有添加其他代码。除非我应该?哦,如果关闭自动布局可以给我更多控制权,那么我会这样做。
  • 你还能发帖吗?什么是description...UILabel?通常你永远不想命名一个属性,因为它是NSObject 上的一个方法。我正在尝试弄清楚您是如何调整该标签的大小的。

标签: ios objective-c uilabel uitableview


【解决方案1】:

通常,我支持可变高度单元格的方法是定义一个类方法,该方法可以计算给定模型对象的大小:

+ (CGFloat)heightForBracket:(Bracket*)bracket;

使其成为类方法的好处在于,您可以与实际实现布局的代码共享常量(填充值、字体大小、缩进级别等),而无需将它们暴露给任何其他类。如果您想在将来更改这些常量,您只需在单元子类中的一处进行更改。一个示例子类实现:

#define kPaddingHorizontal 10.0
#define kPaddingVertical 10.0
#define kFontSizeName 17.0

+ (CGFloat)heightForBracket:(Bracket*)bracket {
    // determine the dimensions of the name
    UIFont *nameFont = [UIFont systemFontOfSize:kFontSizeName];
    CGFloat nameSize = [bracket.name sizeWithFont:nameFont
                                constrainedToSize:CGSizeMake(300, CGFLOAT_MAX) // 300 is the width of your eventual label
                                    lineBreakMode:NSLineBreakByWordWrapping];

    // Apple recommends all cells be at least 44px tall, so we enforce a minimum here
    return MAX(44, nameSize.height + 20 + kPaddingVertical*2); // 20 is space for the subtitle label
}

- (id)initWithReuseIdentifier:(NSString *)reuseIdentifier {
    self = [super initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:reuseIdentifier];

    if (self) {
        // bracket name
        self.textLabel.numberOfLines = 0; // 0 makes this variable height
        self.textLabel.font = [UIFont systemFontOfSize:kFontSizeName];
        self.textLabel.lineBreakMode = NSLineBreakByTruncatingTail;
        self.textLabel.backgroundColor = [UIColor clearColor];
        // if you wanted to hardcode a specific width, to a subview do it here as a constant and then share it with heightForBracket:

        // bracket number
        self.detailTextLabel.numberOfLines = 1;
        self.detailTextLabel.font = [UIFont systemFontOfSize:14.0];
        self.detailTextLabel.lineBreakMode = NSLineBreakByTruncatingTail;
        self.detailTextLabel.backgroundColor = [UIColor clearColor];
    }

    return self;
}

- (void)setBracket:(Bracket*)bracket {
    _bracket = bracket;

    self.textLabel.text = bracket.name;
    self.detailTextLabel.text = [NSString stringWithFormat:@"%@", bracket.bracketId];
}

然后您可以在tableView:heightForRowAtIndexPath: 中调用heightForBracket:

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
    Bracket *bracket = [brackets objectAtIndex:indexPath.row];

    return [BracketTableCell heightForBracket:bracket];
}

tableView:cellForRowAtIndexPath: 变得很简单,只需在单元格上设置相应的括号即可:

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

    if (cell == nil) {
        cell = [[BracketTableCell alloc] initWithReuseIdentifier:CellIdentifier];
    }

    Bracket *bracket = [brackets objectAtIndex:indexPath.row];
    cell.bracket = bracket;  

    return cell;
}

一些注意事项:

  • 这假设单元格没有使用自动布局
  • 这会明​​确硬编码单元格/标签的宽度,可能适合也可能不适合您的用例
  • 你永远不应该将属性命名为description,因为那是method that already exists on the NSObject protocol
  • 其他增强功能将缓存 heightForBracket: 的结果以提高滚动性能,尤其是当您开始为大量子视图执行大小调整逻辑时

【讨论】:

    【解决方案2】:

    @gdubs 你可以使用自定义 UITableViewCells

    您可以使用Customize Table View Cells for UITableView作为参考

    我想那时你自定义 UILabel 会很容易。比如如果你想添加多行然后设置TitletLabel.numberOfLines=0;,如果你想换行TitleLabel.lineBreakMode=NSLineBreakByWordWrapping;。自动换行还有其他选项。

    【讨论】:

    • 我就是这么做的。但它仍然会以同样的方式显示。它也不会调整高度。如果你注意到它就在这里 >> cell.description.numberOfLines = 0; cell.description.font = [UIFont fontWithName:@"Helvetica" size:14.0];
    • @gdubs 不要按照我提供的参考链接尝试自定义单元格。它有适当的解释和更清晰的实施。
    • 是一样的。这就是我学会在我的桌子上应用自定义单元格的地方。
    • @gdubs 好的,试试TitleLabel.lineBreakMode = NSLineBreakByTruncatingTail;。还将标签宽度设置为 arnd 280 - 300,并将标签的高度增加到 35,因为字体大小为 14。然后检查您是否面临同样的问题。
    【解决方案3】:

    使用标签和自动布局的关键是在标签上设置preferredMaxLayoutWidth 属性。没有这个标签就不能正确包装(或者在某些情况下,这就是你以前看到的,我想?)。

    将该值设置为最大线宽,然后标签应该会正常运行。

    【讨论】:

      【解决方案4】:

      我认为问题与标签的宽度有关,如果您使用自动布局,请扩展标签的宽度以填充父单元格并添加尾随并导致超级视图 约束,以便它随之调整大小。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-12-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多