我有一个UILabel,它有两行文字的空间。有时,当文本太短时,此文本会显示在标签的垂直中心。
如何垂直对齐文本,使其始终位于UILabel的顶部?
我有一个UILabel,它有两行文字的空间。有时,当文本太短时,此文本会显示在标签的垂直中心。
如何垂直对齐文本,使其始终位于UILabel的顶部?
当前回答
您可以通过代码或简单地在故事板上执行以下操作来解决此问题:
将UILabel的行数设置为0。将UILabel嵌入UIView中。设置UIView约束(顶部、右侧、左侧和底部),以占用UILabel应增长到的最大空间。然后将UILabel设置为UIView的顶部、右侧和左侧,并将约束设置为底部,距离>=0。
其他回答
我重复了戴莱辛的建议,并添加了一个UIEdgeInset,以允许调整边距。周围环境不错。
- (id)init
{
if (self = [super init]) {
contentEdgeInsets = UIEdgeInsetsZero;
}
return self;
}
- (void)layoutSubviews
{
CGRect localBounds = self.bounds;
localBounds = CGRectMake(MAX(0, localBounds.origin.x + contentEdgeInsets.left),
MAX(0, localBounds.origin.y + contentEdgeInsets.top),
MIN(localBounds.size.width, localBounds.size.width - (contentEdgeInsets.left + contentEdgeInsets.right)),
MIN(localBounds.size.height, localBounds.size.height - (contentEdgeInsets.top + contentEdgeInsets.bottom)));
for (UIView *subview in self.subviews) {
if ([subview isKindOfClass:[UILabel class]]) {
UILabel *label = (UILabel*)subview;
CGSize lineSize = [label.text sizeWithFont:label.font];
CGSize sizeForText = [label.text sizeWithFont:label.font constrainedToSize:localBounds.size lineBreakMode:label.lineBreakMode];
NSInteger numberOfLines = ceilf(sizeForText.height/lineSize.height);
label.numberOfLines = numberOfLines;
label.frame = CGRectMake(MAX(0, contentEdgeInsets.left), MAX(0, contentEdgeInsets.top), localBounds.size.width, MIN(localBounds.size.height, lineSize.height * numberOfLines));
}
}
}
此代码帮助您使文本与顶部对齐,并使标签高度与文本内容固定。
使用以下代码的说明
默认情况下,isHeightToChange会自动将标签的高度设置为与文本内容相同。isHeightToChange如果为false,则使文本对齐到顶部,而不降低标签的高度。
#import "DynamicHeightLable.h"
@implementation DynamicHeightLable
@synthesize isHeightToChange;
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self)
{
// Initialization code.
self.isHeightToChange=FALSE;//default
}
return self;
}
- (void)drawTextInRect:(CGRect)rect
{
if(!isHeightToChange){
CGSize maximumLabelSize = CGSizeMake(self.frame.size.width,2500);
CGFloat height = [self.text sizeWithFont:self.font
constrainedToSize:maximumLabelSize
lineBreakMode:self.lineBreakMode].height;
if (self.numberOfLines != 0) {
height = MIN(height, self.font.lineHeight * self.numberOfLines);
}
rect.size.height = MIN(rect.size.height, height);
}
[super drawTextInRect:rect];
}
- (void) layoutSubviews
{
[super layoutSubviews];
if(isHeightToChange){
CGRect ltempFrame = self.frame;
CGSize maximumLabelSize = CGSizeMake(self.frame.size.width,2500);
CGFloat height = [self.text sizeWithFont:self.font
constrainedToSize:maximumLabelSize
lineBreakMode:self.lineBreakMode].height;
if (self.numberOfLines != 0) {
height = MIN(height, self.font.lineHeight * self.numberOfLines);
}
ltempFrame.size.height = MIN(ltempFrame.size.height, height);
ltempFrame.size.height=ltempFrame.size.height;
self.frame=ltempFrame;
}
}
@end
我在应用程序中所做的是将UILabel的line属性设置为0,并创建UILabel的底部约束,并确保其设置为>=0,如下图所示。
子类UILabel并约束绘图矩形,如下所示:
- (void)drawTextInRect:(CGRect)rect
{
CGSize sizeThatFits = [self sizeThatFits:rect.size];
rect.size.height = MIN(rect.size.height, sizeThatFits.height);
[super drawTextInRect:rect];
}
我尝试了涉及换行填充的解决方案,在某些情况下遇到了错误的行为。根据我的经验,如上所述约束绘图矩形比使用numberOfLines更容易。
P.S.你可以想象一下这样轻松地支持UIViewContentMode:
- (void)drawTextInRect:(CGRect)rect
{
CGSize sizeThatFits = [self sizeThatFits:rect.size];
if (self.contentMode == UIViewContentModeTop) {
rect.size.height = MIN(rect.size.height, sizeThatFits.height);
}
else if (self.contentMode == UIViewContentModeBottom) {
rect.origin.y = MAX(0, rect.size.height - sizeThatFits.height);
rect.size.height = MIN(rect.size.height, sizeThatFits.height);
}
[super drawTextInRect:rect];
}
对于那些使用自定义表单元格试图解决此问题的人,请将其添加到自定义表单元格类中:
斯威夫特2.2:
override func layoutSubviews() {
labelName.sizeToFit()
}
这解决了我的问题。