我有一个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()
}

这解决了我的问题。