ios 在 UILabel 中垂直对齐文本(注意:使用 AutoLayout)
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/28605341/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Vertically align text within a UILabel (Note : Using AutoLayout)
提问by MELWIN
回答by Daniel Galasko
Edit
编辑
In my original answer I was using the paragraph style of the label. Turns out that for multi-line labels this actually prevents the label from being multi-line. As a result I removed it from the calculation. See more about this in Github
在我的原始答案中,我使用了标签的段落样式。事实证明,对于多行标签,这实际上可以防止标签成为多行。结果我从计算中删除了它。在Github 中查看更多相关信息
For those of you more comfortable with using Open Source definitely look at TTTAttributedLabelwhere you can set the label's text alignment to TTTAttributedLabelVerticalAlignmentTop
对于那些更习惯使用开源的人,请务必查看TTTAttributedLabel,您可以在其中将标签的文本对齐方式设置为TTTAttributedLabelVerticalAlignmentTop
The trick is to subclass UILabel
and override drawTextInRect
. Then enforce that the text is drawn at the origin of the label's bounds.
诀窍是子类化UILabel
和覆盖drawTextInRect
. 然后强制在标签边界的原点绘制文本。
Here's a naive implementation that you can use right now:
这是您现在可以使用的简单实现:
Swift
迅速
@IBDesignable class TopAlignedLabel: UILabel {
override func drawTextInRect(rect: CGRect) {
if let stringText = text {
let stringTextAsNSString = stringText as NSString
var labelStringSize = stringTextAsNSString.boundingRectWithSize(CGSizeMake(CGRectGetWidth(self.frame), CGFloat.max),
options: NSStringDrawingOptions.UsesLineFragmentOrigin,
attributes: [NSFontAttributeName: font],
context: nil).size
super.drawTextInRect(CGRectMake(0, 0, CGRectGetWidth(self.frame), ceil(labelStringSize.height)))
} else {
super.drawTextInRect(rect)
}
}
override func prepareForInterfaceBuilder() {
super.prepareForInterfaceBuilder()
layer.borderWidth = 1
layer.borderColor = UIColor.blackColor().CGColor
}
}
Swift 3
斯威夫特 3
@IBDesignable class TopAlignedLabel: UILabel {
override func drawText(in rect: CGRect) {
if let stringText = text {
let stringTextAsNSString = stringText as NSString
let labelStringSize = stringTextAsNSString.boundingRect(with: CGSize(width: self.frame.width,height: CGFloat.greatestFiniteMagnitude),
options: NSStringDrawingOptions.usesLineFragmentOrigin,
attributes: [NSFontAttributeName: font],
context: nil).size
super.drawText(in: CGRect(x:0,y: 0,width: self.frame.width, height:ceil(labelStringSize.height)))
} else {
super.drawText(in: rect)
}
}
override func prepareForInterfaceBuilder() {
super.prepareForInterfaceBuilder()
layer.borderWidth = 1
layer.borderColor = UIColor.black.cgColor
}
}
Objective-C
目标-C
IB_DESIGNABLE
@interface TopAlignedLabel : UILabel
@end
@implementation TopAlignedLabel
- (void)drawTextInRect:(CGRect)rect {
if (self.text) {
CGSize labelStringSize = [self.text boundingRectWithSize:CGSizeMake(CGRectGetWidth(self.frame), CGFLOAT_MAX)
options:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading
attributes:@{NSFontAttributeName:self.font}
context:nil].size;
[super drawTextInRect:CGRectMake(0, 0, ceilf(CGRectGetWidth(self.frame)),ceilf(labelStringSize.height))];
} else {
[super drawTextInRect:rect];
}
}
- (void)prepareForInterfaceBuilder {
[super prepareForInterfaceBuilder];
self.layer.borderWidth = 1;
self.layer.borderColor = [UIColor blackColor].CGColor;
}
@end
Since I used IBDesignable you can add this label to a storyboard and watch it go, this is what it looks like for me
由于我使用了 IBDesignable,您可以将此标签添加到故事板并观看它,这就是我的样子
回答by Nikola Milicevic
If you're not restricted by having UILabel of fixed size, instead of aligning the text within a UILabel, simply use ≥ constraint on the given label to change the size of it.
如果您不受 UILabel 固定大小的限制,而不是在 UILabel 内对齐文本,只需在给定标签上使用 ≥ 约束来更改其大小。
It's the most elegant solution using Auto Layout. Don't forget to set numberOfLinesto zero though.
这是使用自动布局的最优雅的解决方案。不要忘记将numberOfLines设置为零。
回答by arturdev
You can use UITextView instead of UILabel:
Uncheck "Scrolling enabled"
Uncheck "Editable"
Uncheck "Selectable"
Set background color to ClearColor
您可以使用 UITextView 而不是 UILabel:
取消选中“启用滚动”
取消选中“可编辑”
取消选中“可选”
将背景颜色设置为 ClearColor
回答by Oyvkva
回答by Felipe FMMobile
Instead, I changed the Bottom Space Constant to priority @250 and solved my problem. And my label has height constant with <= constant
相反,我将底部空间常数更改为优先级 @250 并解决了我的问题。我的标签具有 <= 常量的高度常量
回答by Wain
You would do that by removing the minimum height.
您可以通过删除最小高度来做到这一点。
If you need the minimum height to something else below the label then you would use a container view that resized based on the label contents but used a minimum.
如果您需要标签下方其他东西的最小高度,那么您将使用根据标签内容调整大小但使用最小值的容器视图。
回答by ezchen
I used @Daniel Golasko's solution and whenever the text inside the UILabel was longer than the UILabel could contain, the text would start moving down instead of staying aligned to top.
我使用了@Daniel Golasko 的解决方案,每当 UILabel 中的文本长于 UILabel 可以包含的长度时,文本就会开始向下移动而不是保持与顶部对齐。
I changed this line to make sure the text is aligned properly
我更改了这一行以确保文本正确对齐
[super drawTextInRect:CGRectMake(0, 0, ceilf(CGRectGetWidth(self.frame)),MIN(ceilf(labelStringSize.height), self.frame.size.height))];
回答by P?tur Magnussen
I had a similiar issue where there were 3 labels. The middle label could have much longer text than the other two, so its height could grow much larger.
我有一个类似的问题,有 3 个标签。中间标签的文本可能比其他两个标签长得多,因此它的高度可以变得更大。
Like this:
像这样:
I set the middle label's bottom space constraint to be >= the bottom label.
我将中间标签的底部空间约束设置为 >= 底部标签。
That solved my problem.
那解决了我的问题。
回答by Alexander Poleschuk
There is an easy solution for cases where the height of a label doesn't need to be constant: put your Label
in a Stack View
. Be sure to add leading and trailing constants to the Stack View
. Here is a screenshot of how to do it in storyboard:
对于标签高度不需要恒定的情况,有一个简单的解决方案:将您Label
的Stack View
. 确保将前导和尾随常量添加到Stack View
. 这是如何在故事板中执行此操作的屏幕截图:
回答by dimpiax
Swift 4
斯威夫特 4
You should subclass UILabel and override text display rendering.
您应该继承 UILabel 并覆盖文本显示渲染。
class UITopAlignedLabel: UILabel {
override func drawText(in rect: CGRect) {
guard let string = text else {
super.drawText(in: rect)
return
}
let size = (string as NSString).boundingRect(
with: CGSize(width: rect.width, height: .greatestFiniteMagnitude),
options: [.usesLineFragmentOrigin],
attributes: [.font: font],
context: nil).size
var rect = rect
rect.size.height = size.height.rounded()
super.drawText(in: rect)
}
}