UILabel 的 sizeToFit/sizeThatFits 忽略 numberoflines 属性
Posted
技术标签:
【中文标题】UILabel 的 sizeToFit/sizeThatFits 忽略 numberoflines 属性【英文标题】:UILabel's sizeToFit/sizeThatFits ignore the numberoflines property 【发布时间】:2011-02-18 13:30:46 【问题描述】:问题:确定UILabel
需要的大小(行数),假设宽度为 300 像素。字符串较长,所以我将lineBreakMode
设置为UILineBreakModeWordWrap
并调用sizeThatFits
来尝试确定大小。但它在单行中给出了 457 像素的宽度,而不是预期的两行中的 300 像素。
请看:
CGSize available = CGSizeMake(300, INFINITY);
UILabel *label = [[[UILabel alloc] initWithFrame:CGRectMake(0, 0, 300, 400)] autorelease];
label.text = title;
label.lineBreakMode = UILineBreakModeWordWrap;
label.font = [UIFont fontWithName:kBoldFont size:kTitleFontSize];
label.numberOfLines = 3;
CGSize sizedtoFit = [label sizeThatFits:available];
但我发现 sizedtoFit 变量的宽度为 457 像素,高度为 22 像素,并且 UI 显示单行并带有剪切的文本。我预计两条线的宽度为 300 像素,高度为 44 像素。
numberoflines 的 UILabel 文档说:
当使用sizeToFit
方法调整接收器的大小时,调整大小会考虑存储在此属性中的值。例如,如果此属性设置为 3,sizeToFit
方法会调整接收器的大小,使其大到足以显示三行文本。
我尝试了以下各种组合:
-
将
CGRectZero
传递给 init 函数,传递 300x400 或 300 x 无穷大。
在创建后设置框架,而不是将其传递给 init
函数。
调用 [sizeToFit]
并希望它在假设当前宽度的情况下计算高度,但事实并非如此。
调用 sizeToFit,然后调用 sizeThatFits`。
调用layoutIfNeeded
。
它们都不起作用。我做错了什么,或者这是文档和框架实现不一致的错误?谢谢。
【问题讨论】:
根据文档,我认为这是一个错误,我刚刚报告了它。 这似乎在 ios6 中已修复 - [ sizeToFit] 现在将 numberOfLines 考虑在内。 @Pavel 是对的,刚刚从 5.1 升级到 6.0 并且神奇地sizeToFit
返回了正确的大小(增加了高度)。
【参考方案1】:
我遇到了同样的问题,适合的尺寸只是忽略了尺寸... /: 我最终使用了:
CGRect textSize = [UILabel textRectForBounds:CGRectMake(0, 0, 300, CGFLOAT_MAX)
limitedToNumberOfLines:3];
像魅力一样工作...... :)
文档说你不应该直接调用它,但我已经使用它一段时间了,有批准的提交应用程序,一切都很棒...... :)
【讨论】:
除非万不得已,否则我不会这样做 :) 想详细说明@KartickVaddadi 吗? :) 好吧,我不想做文档上说不应该做的事情,除非万不得已。 这是否假定您使用的是默认字体? 使用实例方法CGRect textSize = [label textRectForBounds:CGRectMake(0, 0, 300, CGFLOAT_MAX) limitedToNumberOfLines:3]
的当前文档似乎很好。注意:这不是@AlexZak 回答中的类方法。参考:developer.apple.com/library/ios/documentation/uikit/reference/…:【参考方案2】:
你试过sizeWithFont: constrainedToSize: lineBreakMode:
方法吗?
例如:
CGSize sizeToFit = [title sizeWithFont:label.font constrainedToSize:label.frame.size lineBreakMode:label.lineBreakMode];
【讨论】:
那是我的后备选项,但问题是:为什么 sizeThatFits 不能正常工作?刚刚有人告诉我,如果我将 numberOfLines 设置为 0(无限制),它会起作用。 如果您想要最多三行,就像暗示的问题一样,这并不好。猜猜我需要计算三行的高度,然后将其传递给 sizeWithFont 函数。这很糟糕。 很好的答案。我发现这对多行标签最有用。不过,在 iOS7 中不推荐使用 sizeWithFont。使用 boundingRectWithSize 查看我的单独答案:【参考方案3】:我发现 Ian L 的答案最好使用 -sizeWithFont:constrainedToSize:lineBreakMode:
,不幸的是 sizeWithFont: 在 iOS7 下已弃用。
这就是 sizeWithFont: 在 iOS7 中为 UILabel 子类工作的方式:
NSRange range = NSMakeRange(0, self.attributedText.length);
sizeToFit = [self.text boundingRectWithSize:self.bounds.size
options:NSStringDrawingUsesLineFragmentOrigin
attributes:[self.attributedText
attributesAtIndex:0 effectiveRange:&range] context:nil].size;
【讨论】:
【参考方案4】:我认为你得到了意想不到的结果,因为你没有考虑到UILabel
的字体。请尝试以下操作:
UILabel *label = [[[UILabel alloc] initWithFrame:CGRectMake(0, 0, 300, 400)] autorelease];
label.text = title;
label.lineBreakMode = UILineBreakModeWordWrap;
label.font = [UIFont fontWithName:kBoldFont size:kTitleFontSize];
label.numberOfLines = 0;
CGSize size = [label.text sizeWithFont:label.font constrainedToSize:CGSizeMake(label.frame.size.width,FLT_MAX) lineBreakMode:UILineBreakModeWordWrap ];
label.frame = CGRectMake(label.frame.origin.x,label.frame.origin.y,label.frame.size.width,size.height);
【讨论】:
此方案不限制行数 除了不限制行数之外,它还使用了NSString的大小调整方法,这将忽略UILabel的大量附加功能【参考方案5】:sizeToFit
的 ios5 没有解决方案。您可以使用其他解决方案,如sizeWithFont
等。在 ios6 中,该问题已修复。但是,我的解决方案有以下解决方法:
int lineCount = myLabel.numberOfLines;
myLabel.numberOfLines = 0;
[myLabel sizeToFit];
myLabel.numberOfLines = lineCount;
而且它有效。请注意,对于我的情况,标签的宽度是固定的,我只需要 sizeToFit 来调整高度。
【讨论】:
【参考方案6】:这一切都已弃用。使用 boundingRectWithSize
【讨论】:
以上是关于UILabel 的 sizeToFit/sizeThatFits 忽略 numberoflines 属性的主要内容,如果未能解决你的问题,请参考以下文章
如何调整 UIView 的大小以获取大量 UILabel 并调整 UILabel 的大小以适合文本?
UIAlertController 或 UITextField 中的 UILabel 类似 UILabel