【问题标题】:uitableviewcell textlabel too long and push detailtextlabel out of viewuitableviewcell textlabel 太长并将 detailtextlabel 推到视野之外
【发布时间】:2011-04-21 15:02:23
【问题描述】:

当我使用 UITableViewCellStyleValue1 时,我得到了一长串 textLabel,并且不知何故 detailTextLabel 从视图中被推出。

当我把我的 textLabel 文本做短时,我可以看到 detailTextLabel 的文本。

有没有办法限制上述样式中的textLabel的宽度,以便它会截断太长的textLabel?

我的代码是:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

static NSString *CellIdentifier = @"Cell";

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

}

cell.textLabel.lineBreakMode = UILineBreakModeTailTruncation;

//---get the letter in each section; e.g., A, B, C, etc.---
NSString *alphabet = [self.currencyNameIndex objectAtIndex:[indexPath section]];

//---get all states beginning with the letter---
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF beginswith[c] %@", alphabet];
self.currencyList = [self.keyCurrencyName filteredArrayUsingPredicate:predicate];

if ([self.currencyList count] > 0) 
{
    NSString *currencyName = [self.keyCurrencyName objectAtIndex:indexPath.row];
    cell.textLabel.text = currencyName;

    NSString *currencyCode = [self.valueCurrencyCode objectAtIndex:indexPath.row];
    cell.detailTextLabel.text = currencyCode;

}   

return cell;
}

所以我的货币名称在某些条目上会很长。

【问题讨论】:

  • 是不是和Table View Programming Guide for iOS中的图1-8一样?
  • 是的。正确的尼克。除了我的 detailTextLabel 固定为 3 个字符,但 textLabel 会很长,所以我需要截断 textLabel,如图 1-8 所示
  • 奇怪,它应该默认截断。你设置了textLabel的linebreakmode了吗?
  • 粘贴了代码。是的,也尝试设置换行模式,但没有运气
  • 更奇怪。可以发截图吗?并请转储文本看起来不正确的单元格的 textLabel 框架。

标签: iphone uitableview textlabel


【解决方案1】:

对我来说最简单的就是继承 UITableViewCell 并覆盖 layoutSubviews。

找不到可靠的方法来仅从标签帧计算位置,因此在这种情况下,只是硬编码了具有 UITableViewCellAccessoryDisclosureIndicator 附件类型的 UITableViewCellStyleValue1 单元格的附件宽度。

- (void)layoutSubviews
{
    [super layoutSubviews];

    CGFloat detailTextLabelWidth = [self.detailTextLabel.text sizeWithFont:self.detailTextLabel.font].width;
    CGRect detailTextLabelFrame = self.detailTextLabel.frame;

    if (detailTextLabelFrame.size.width <= detailTextLabelWidth && detailTextLabelWidth > 0) {
        detailTextLabelFrame.size.width = detailTextLabelWidth;
        CGFloat accessoryWidth = (floor(NSFoundationVersionNumber) <= NSFoundationVersionNumber_iOS_6_1) ? 28.0f : 35.0f;
        detailTextLabelFrame.origin.x = self.frame.size.width - accessoryWidth - detailTextLabelWidth;
        self.detailTextLabel.frame = detailTextLabelFrame;

        CGRect textLabelFrame = self.textLabel.frame;
        textLabelFrame.size.width = detailTextLabelFrame.origin.x - textLabelFrame.origin.x;
        self.textLabel.frame = textLabelFrame;
    }
}

【讨论】:

  • 直接计算附件宽度更好const CGFloat accessoryWidth = CGRectGetWidth(self.bounds) - CGRectGetMaxX(detailTextLabelFrame)
【解决方案2】:

@Jhaliya @卢卡斯

cell.textLabel.numberOfLines = 3; // set the numberOfLines
cell.textLabel.lineBreakMode = UILineBreakModeTailTruncation;

请看这里:Custom UITableViewCell. Failed to apply UILineBreakModeTailTruncation

【讨论】:

  • 它就像一个魅力。只需将UILineBreakModeTailTruncation 替换为NSLineBreakByTruncatingTail(iOS6 后已弃用)。
【解决方案3】:

我在 UITableView 中尝试使用“Right Detail”时遇到了类似的问题;正确的细节内置标题标签正在破坏我的字幕标签。

最终我放弃了“正确的细节”,转而使用自己的自定义(使用 swift 和自动布局):

  1. 我创建了自己的继承自 UITableViewCell 的简单类:

    class TransactionCell: UITableViewCell
    {
    
    }
    
  2. 我通过将“表格视图单元格”菜单上的“样式”字段设置为“自定义”并将“TransactionCell”添加到“自定义”的“类”字段中,将我的原型单元格设置为使用该自定义类类”菜单。当您在情节提要中选择原型单元格时,这些菜单可用。

  3. 我在原型单元格中添加了两个标签,并通过右键单击从标签拖动到我的类将它们连接到我的自定义类(奇怪的是,我必须清理我的构建才能让我这样做):

    class TransactionCell: UITableViewCell{
    
        @IBOutlet weak var detailsLabel: UILabel!
    
        @IBOutlet weak var amountLabel: UILabel!
    
    }
    
  4. 我利用 swift 的自动布局功能为标签添加了新的约束(您需要设置这些以符合自己的要求;如果遇到困难,请参阅有关自动布局的教程)

  1. ...并在各自的“标签”菜单中设置“行”和“换行符”字段,以便标签之间的间距均匀,以便我的详细信息标签可以弯曲成多行。

它对我有用,让我可以灵活地在每个单元格中快速地在 UITableView 中使用不同数量的多行,同时格式化自动换行,使其看起来漂亮甚至均匀,就像我预期的“正确的细节"自动执行。

【讨论】:

  • 这应该是公认的答案。如果您是一名认真的开发人员并且知道您需要大量的 tableViews,那么您应该立即将单元格子类化为一种习惯。
【解决方案4】:

我遇到了同样的问题,不得不创建一个 UITableViewCell 子类。这样做比我想象的要容易:

基本上就是新建一个文件,就是 UITableViewCell 的子类

添加标签并合成它们:

// in the .h file
@property (nonatomic, weak) IBOutlet UILabel *textLabel;
@property (nonatomic, weak) IBOutlet UILabel *detailTextLabel;
// in the .m file
@synthesize textLabel, detailTextLabel;

在 StoryBoard 中,将您的类设置为单元格的类,将样式设置为“自定义”并在单元格中添加两个标签以完全符合您的要求(我让它们看起来与默认值相同:http://cl.ly/J7z3

最重要的部分是确保将标签连接到单元格

您需要从单元格到文档大纲中的标签进行控制单击。这是它的外观图片:http://cl.ly/J7BP

帮助我了解如何创建自定义单元格、动态单元格和静态单元格的是这个 youtube 视频:http://www.youtube.com/watch?v=fnzkcV_XUw8

一旦你这样做了,你应该准备好了。祝你好运!

【讨论】:

    【解决方案5】:

    支持最新iOS(12)的Swift版本:

    override func layoutSubviews() {
        super.layoutSubviews()
        guard let detailWidth = detailTextLabel?.intrinsicContentSize.width, var detailFrame = detailTextLabel?.frame else {
            return
        }
    
        let padding = layoutMargins.right
        if (detailFrame.size.width <= detailWidth) && (detailWidth > 0) {
            detailFrame.size.width = detailWidth
            detailFrame.origin.x = frame.size.width - detailWidth - padding
            detailTextLabel?.frame = detailFrame
    
            var textLabelFrame = textLabel!.frame
            textLabelFrame.size.width = detailFrame.origin.x - textLabelFrame.origin.x - padding
            textLabel?.frame = textLabelFrame
        }
    }
    

    【讨论】:

      【解决方案6】:

      调整视图的框架:textLabel

       CGRect aFrame = cell.textLabel.frame;
       aFrame.size.width = 100;  // for example
       cell.textLabel.frame = aFrame;
      

      【讨论】:

      • 这仍然没有运气。宽度似乎没有得到调整
      • 我相信你不能真正配置UITableViewCell中默认textLabel和detailTextLabel的框架。如果您希望能够配置 textLabels 的框架,您应该创建自己的 UITableViewCell 子类。默认单元格的框架不可配置,因为它与其他组件的大小有关,例如 imageView 和附件视图,如果这些组件调整大小,它们将强制标签调整大小。
      【解决方案7】:

      更新了 Gosoftworks Development 的答案。

      斯威夫特 3

      class BaseTableViewCell: UITableViewCell {
          override func layoutSubviews() {
              super.layoutSubviews()
      
              guard let tl = textLabel, let dl = detailTextLabel else { return }
              if (tl.frame.maxX > dl.frame.minX) {
                   tl.frame.size.width = dl.frame.minX - tl.frame.minX - 5        
              }
          }
      }
      

      【讨论】:

        【解决方案8】:

        创建一个包含 UILabel 的自定义 UITableViewCell,您可以随意控制它,或者截断分配给基类 textLabel 的文本以适应您拥有的空间。

        这并不完美,但我在自定义单元格过大的地方使用了文本截断技术(例如,当唯一的问题是适合文本时)使用类似于以下方法的 NSString 类别:

        - (NSString *)stringByTruncatingToWidth:(CGFloat)width withFont:(UIFont *)font
        {
            NSString *result = [NSString stringWithString:self];
        
            while ([result sizeWithFont:font].width > width)
            {
                result = [result stringByReplacingOccurrencesOfString:@"..." withString:[NSString string]];
        
                result = [[result substringToIndex:([result length] - 1)] stringByAppendingString:@"..."];
            }
        
            return result;
        }
        

        可能没有“优化”,但它适用于简单的场景。

        【讨论】:

          【解决方案9】:

          1st:设置换行模式

          textLabel.lineBreakMode = NSLineBreakByTruncatingTail;
          

          第二个:设置你想要的texLabel框架宽度(例如200)

          CGRect textFrame = self.textLabel.frame;
          CGRect newTextFrame = CGRectMake(textFrame.origin.x, textFrame.origin.y, 200, textFrame.size.height);
          self.textLabel.frame = newTextFrame;
          

          【讨论】:

            【解决方案10】:

            有效!!但我只是更改了 Christopher King 的代码:

            - (NSString *)stringByTruncatingToWidth:(CGFloat)width withFont:(UIFont *)font :(NSString*) result
            {
            
                while ([result sizeWithFont:font].width > width)
                {
                    result = [result stringByReplacingOccurrencesOfString:@"..." withString:[NSString string]];
            
                    result = [[result substringToIndex:([result length] - 1)] stringByAppendingString:@"..."];
                }
            
                return result;
            }
            

            及用法:

            NSString* text = @"bla bla bla some long text bla bla";
            text = [self stringByTruncatingToWidth:cell.frame.size.width-70.0 withFont:[UIFont systemFontOfSize:17] :text];
            cell.textLabel.text = text;
            

            【讨论】:

              【解决方案11】:

              我已经为此苦苦挣扎,并找到了一个非常简单的答案。我的textLabel 在左边,会把右边的detailText 推到你有时根本看不到的地方。

              我的解决方案,将 Table View Cell styleLeft DetailRight Detail 更改为 Subtitle。如果您不介意 detailText 在下方而不是在右侧或左侧,则此解决方案有效。

              如果您对行高有疑问,可以使用下面viewDidLoad 中的代码进行调整。

                  self.tableView.estimatedRowHeight = 500 // set this as high as you might need, although I haven't tested alternatives
                  self.tableView.rowHeight = UITableViewAutomaticDimension
                  self.tableView.reloadData()
              

              【讨论】:

                【解决方案12】:

                使用 UILabel lineBreakMode 属性将文本限制在 UILabel 的宽度内

                @property(nonatomic) UILineBreakMode lineBreakMode
                

                如下使用。

                myLabel.lineBreakMode = UILineBreakModeTailTruncation;
                

                这里是可用于lineBreakMode 的值列表。

                http://developer.apple.com/library/ios/#documentation/uikit/reference/NSString_UIKit_Additions/Reference/Reference.html#//apple_ref/doc/c_ref/UILineBreakMode

                已编辑:

                根据您的要求设置UILabel 的宽度

                例如。

                myLabel.frame.size.width = 320;
                

                【讨论】:

                • UILabel 有效。但是当我将相同的应用于 textLabel 时: cell.textLabel.lineBreakMode = UILineBreakModeTailTruncation;那么这不会截断我的 textLabel
                • 如果您尝试使用 cell.textLabel.frame.size.width = 320;,您将收到一个编译器错误,指出“表达式不可分配”——所以我认为这不适用于所描述的场景。
                • 我不确定为什么这是公认的答案,因为它不能解决发布的问题。默认情况下,单元格的textLabel 已经使用NSLineBreakByTruncatingTail。如果不继承UITableViewCell,就无法更改标签的宽度。
                猜你喜欢
                • 2011-01-16
                • 2011-06-10
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多