[self.Review sizeToFit];
sizeToFit之前的结果:
NSStringFromCGRect(self.Review.frame): {{90, 20}, {198, 63}}
sizeToFit后的结果:
NSStringFromCGRect(self.Review.frame): {{90, 20}, {181, 45}}
我希望宽度保持不变。我只是想改变身高。自动遮罩是
(lldb) po self.Review
(UILabel *) $1 = 0x08bb0fe0 <UILabel: 0x8bb0fe0; frame = (90 20; 181 45); text = 'I'm at Mal Taman Anggrek ...'; clipsToBounds = YES; opaque = NO; autoresize = LM+RM+H; userInteractionEnabled = NO; layer = <CALayer: 0x8bb68b0>>
我知道有办法这样做: How to adjust and make the width of a UILabel to fit the text size?
答案要么很奇怪(我们需要重新补充字体信息)。或者不清楚。
您还需要定义最大宽度,然后告诉您的程序 如果sizeToFit为您提供的宽度大于该最大值,该怎么办。
我将使用使用sizeWithFont
的奇怪解决方案。这很奇怪,因为UILabel已经知道标签中的字体了。
实际上sizeToFit究竟是如何表现的?它如何决定我们是否需要更薄或更高的UILabel?
答案 0 :(得分:40)
这就是它的完成方式。因为标签已经包含了字体信息,所以在这种方法中包含它很简单。
CGSize size = [label.text sizeWithFont:label.font
constrainedToSize:CGSizeMake(maxWidth, MAXFLOAT)
lineBreakMode:UILineBreakModeWordWrap];
CGRect labelFrame = label.frame;
labelFrame.size.height = size.height;
label.frame = labelFrame;
使用更新boundingRectWithSize
:
let maxHeight = CGFloat.infinity
let rect = label.attributedText?.boundingRectWithSize(CGSizeMake(maxWidth, maxHeight),
options: .UsesLineFragmentOrigin, context: nil)
var frame = label.frame
frame.size.height = rect.size.height
label.frame = frame
答案 1 :(得分:40)
您可以使用sizeThatFits获得相同的结果。
CGSize size = [label sizeThatFits:CGSizeMake(label.frame.size.width, CGFLOAT_MAX)];
CGRect frame = label.frame;
frame.size.height = size.height;
label.frame = frame;
或者,使用sizeToFit。
CGRect frame = label.frame;
[label sizeToFit];
frame.size.height = label.frame.size.height;
label.frame = frame;
答案 2 :(得分:17)
sizeToFit效果很好。唯一的问题是它基于控件的当前大小。
例如,如果要使用标签回收表格视图单元格,则标签在前一个单元格中的宽度可能会减小,因此,对sizeToFit的调用可能看起来不可靠。
在发送sizeToFit消息之前,只需重置控件的原始宽度。
答案 3 :(得分:2)
我认为你不应该使用NSString
的{{1}}方法,size...
已经有了一个API,就像@vatrif指出的那样(内部可能只使用{{1}方法)。
尽管如此我认为UILabel
的API可以改进。这就是为什么我认为一个类别将是最优雅的解决方案:
NSString
只有一件事:我不确定该方法的适当名称:
非常感谢评论,谢谢!
答案 4 :(得分:2)
c = CGSize(宽度:yourWidth,身高:CGFloat.greatestFiniteMagnitude)
result = sizeThatFits(c).height
因此...
let t = .... your UITextView
let w = .... your known width of the item
let trueHeight = t.sizeThatFits(
CGSize(width: t, height: CGFloat.greatestFiniteMagnitude)).height
那就是它。
很多时候,你想知道高度 差异与&#34;普通&#34;单行录入。
如果您正在制作某种与UTableView无关的单元格(例如,某种自定义堆栈视图),则会出现这种情况。您必须在某个时刻手动设置高度。在你的故事板上,根据你的意愿构建它,使用任何短字符串的示例文本(例如,&#34; A&#34;),当然在任何正常情况下只有一行。然后你做这样的事......
func setTextWithSizeCorrection() { // an affaire iOS
let t = .... your UITextView
let w = .... your known width of the item
let oneLineExample = "A"
let actualText = yourDataSource[row].description.whatever
// get the height as if with only one line...
experimental.text = oneLineExample
let oneLineHeight = t.sizeThatFits(
CGSize(width: w, height: CGFloat.greatestFiniteMagnitude)).height
// get the height with the actual long text...
// (note that usually, you do not want a one-line minimum)
experimental.text = (actualText == "") ? oneLineExample : actualText
let neededHeight = t.sizeThatFits(
CGSize(width: w, height: CGFloat.greatestFiniteMagnitude)).height
experimental.text = actualText
let delta = neededHeight - oneLineHeight
set the height of your cell, or whatever it is(standardHeight + delta)
}
最后一点:iOS中真正愚蠢的事情之一就是UITextView里面有一个奇怪的边缘。这意味着您无法在UITextViews和标签之间进行交换;它会导致许多其他问题。 Apple还没有解决这个问题。解决问题很困难:以下方法通常都可以:
@IBDesignable class UITextViewFixed: UITextView {
override func layoutSubviews() {
super.layoutSubviews()
setup()
}
func setup() {
textContainerInset = UIEdgeInsets.zero;
textContainer.lineFragmentPadding = 0;
}
}
来自Apple的破坏,无法使用的UITextView ......
在大多数情况下, UITextViewFixed
是可接受的修复:
(为了清楚起见,添加了黄色。)
答案 5 :(得分:1)
同意API将从此添加中受益。让您的生活更轻松,并在Swift中为UILabel类添加扩展,如下所示:
extension UILabel {
func sizeToFitHeight() {
let size:CGSize = self.sizeThatFits(CGSizeMake(self.frame.size.width, CGFloat.max))
var frame:CGRect = self.frame
frame.size.height = size.height
self.frame = frame
}
}
答案 6 :(得分:1)
SWIFT 3的固定解决方案
将CGFloat.greatestFiniteMagnitude
用于maxHeight。
let size = CGSize.init(width: yourLabel.frame.size.width,
height: CGFloat.greatestFiniteMagnitude)
let rect = errorLabel.attributedText?.boundingRect(with: size, options: .usesLineFragmentOrigin, context: nil)
var frame = errorLabel.frame
frame.size.height = (rect?.size.height)!
errorLabel.frame = frame
或创建UIlabel
扩展名,并调用方法yourLabel. sizeToFitHeight()
extension UILabel {
func sizeToFitHeight() {
let maxHeight : CGFloat = CGFloat.greatestFiniteMagnitude
let size = CGSize.init(width: self.frame.size.width, height: maxHeight)
let rect = self.attributedText?.boundingRect(with: size, options: .usesLineFragmentOrigin, context: nil)
var frame = self.frame
frame.size.height = (rect?.size.height)!
self.frame = frame
}
}
答案 7 :(得分:1)
Swift 3的这个问题的简单扩展。
extension UILabel {
func sizeToFitHeight() {
let size: CGSize = self.sizeThatFits(CGSize.init(width: self.frame.size.width, height: CGFloat.greatestFiniteMagnitude))
var frame:CGRect = self.frame
frame.size.height = size.height
self.frame = frame
}
}
答案 8 :(得分:0)
Swift 3版Mundi的答案:
let maxHeight: CGFloat = 10000
let rect = label.attributedText!.boundingRect(with: CGSize(width: maxWidth, height: maxHeight),
options: .usesLineFragmentOrigin,
context: nil)
var frame = labe.frame
frame.size.height = rect.size.height
label.frame = frame
答案 9 :(得分:0)
我相信我有一个简单得多的解决方案:
let oldWidth = self.frame.size.width
label.sizeToFit()
label.frame.size.width = oldWidth
只需存储原来的宽度,sizeToFit()
既适用于宽度,又适用于高度,然后将宽度重新设置为原来的值,而仅更改标签的高度。