我有一个UILabel,它有两行文字的空间。有时,当文本太短时,此文本会显示在标签的垂直中心。

如何垂直对齐文本,使其始终位于UILabel的顶部?


当前回答

就像上面的答案一样,但它不太正确,或者很容易插入代码,所以我稍微清理了一下。将此扩展名添加到它自己的.h和.m文件中,或者直接粘贴到您打算使用的实现上方:

#pragma mark VerticalAlign
@interface UILabel (VerticalAlign)
- (void)alignTop;
- (void)alignBottom;
@end


@implementation UILabel (VerticalAlign)
- (void)alignTop
{
    CGSize fontSize = [self.text sizeWithFont:self.font];

    double finalHeight = fontSize.height * self.numberOfLines;
    double finalWidth = self.frame.size.width;    //expected width of label


    CGSize theStringSize = [self.text sizeWithFont:self.font constrainedToSize:CGSizeMake(finalWidth, finalHeight) lineBreakMode:self.lineBreakMode];


    int newLinesToPad = (finalHeight  - theStringSize.height) / fontSize.height;

    for(int i=0; i<= newLinesToPad; i++)
    {
        self.text = [self.text stringByAppendingString:@" \n"];
    }
}

- (void)alignBottom
{
    CGSize fontSize = [self.text sizeWithFont:self.font];

    double finalHeight = fontSize.height * self.numberOfLines;
    double finalWidth = self.frame.size.width;    //expected width of label


    CGSize theStringSize = [self.text sizeWithFont:self.font constrainedToSize:CGSizeMake(finalWidth, finalHeight) lineBreakMode:self.lineBreakMode];


    int newLinesToPad = (finalHeight  - theStringSize.height) / fontSize.height;

    for(int i=0; i< newLinesToPad; i++)
    {
        self.text = [NSString stringWithFormat:@" \n%@",self.text];
    }
}
@end

然后要使用,请将文本放入标签中,然后调用适当的方法将其对齐:

[myLabel alignTop];

or

[myLabel alignBottom];

其他回答

就像上面的答案一样,但它不太正确,或者很容易插入代码,所以我稍微清理了一下。将此扩展名添加到它自己的.h和.m文件中,或者直接粘贴到您打算使用的实现上方:

#pragma mark VerticalAlign
@interface UILabel (VerticalAlign)
- (void)alignTop;
- (void)alignBottom;
@end


@implementation UILabel (VerticalAlign)
- (void)alignTop
{
    CGSize fontSize = [self.text sizeWithFont:self.font];

    double finalHeight = fontSize.height * self.numberOfLines;
    double finalWidth = self.frame.size.width;    //expected width of label


    CGSize theStringSize = [self.text sizeWithFont:self.font constrainedToSize:CGSizeMake(finalWidth, finalHeight) lineBreakMode:self.lineBreakMode];


    int newLinesToPad = (finalHeight  - theStringSize.height) / fontSize.height;

    for(int i=0; i<= newLinesToPad; i++)
    {
        self.text = [self.text stringByAppendingString:@" \n"];
    }
}

- (void)alignBottom
{
    CGSize fontSize = [self.text sizeWithFont:self.font];

    double finalHeight = fontSize.height * self.numberOfLines;
    double finalWidth = self.frame.size.width;    //expected width of label


    CGSize theStringSize = [self.text sizeWithFont:self.font constrainedToSize:CGSizeMake(finalWidth, finalHeight) lineBreakMode:self.lineBreakMode];


    int newLinesToPad = (finalHeight  - theStringSize.height) / fontSize.height;

    for(int i=0; i< newLinesToPad; i++)
    {
        self.text = [NSString stringWithFormat:@" \n%@",self.text];
    }
}
@end

然后要使用,请将文本放入标签中,然后调用适当的方法将其对齐:

[myLabel alignTop];

or

[myLabel alignBottom];

创建新类

标签顶部对齐

.h文件

#import <UIKit/UIKit.h>


@interface KwLabelTopAlign : UILabel {

}

@end

.m文件

#import "KwLabelTopAlign.h"


@implementation KwLabelTopAlign

- (void)drawTextInRect:(CGRect)rect {
    int lineHeight = [@"IglL" sizeWithFont:self.font constrainedToSize:CGSizeMake(rect.size.width, 9999.0f)].height;
    if(rect.size.height >= lineHeight) {
        int textHeight = [self.text sizeWithFont:self.font constrainedToSize:CGSizeMake(rect.size.width, rect.size.height)].height;
        int yMax = textHeight;
        if (self.numberOfLines > 0) {
            yMax = MIN(lineHeight*self.numberOfLines, yMax);    
        }

        [super drawTextInRect:CGRectMake(rect.origin.x, rect.origin.y, rect.size.width, yMax)];
    }
}

@end

Edit

下面是一个更简单的实现,它也做到了这一点:

#import "KwLabelTopAlign.h"

@implementation KwLabelTopAlign

- (void)drawTextInRect:(CGRect)rect
{
    CGFloat height = [self.text sizeWithFont:self.font
                            constrainedToSize:rect.size
                                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];
}

@end

设置新文本:myLabel.text=@“某些文本”将最大行数设置为0(自动):myLabel.numberOfLines=0将标签的框架设置为最大大小:myLabel.frame=CGRectMake(20,20200800)调用sizeToFit以减小框架大小,使内容刚好适合:[myLabel sizeToFit]

标签框架现在刚好足够高和宽,以适合您的文本。左上角应保持不变。我只测试了左上对齐的文本。对于其他路线,您可能需要随后修改框架。

此外,我的标签启用了换行。

有两种方法可以解决这个问题。一种是

[mylabel setNumberOfLines:0];
[mylabel sizeToFit];

但是第二种方法对于这种方法更可靠,

 CGSize sizeToFit = [label.text sizeWithFont:label.font constrainedToSize:maxSize lineBreakMode:label.lineBreakMode];
 [mylabel setFrame:CGRectMake(mylabel.frame.origin.x, mylabel.frame.origin.y, sizeToFit.width, sizeToFit.height)];

输入“\n”不是一件好事,但如果您知道将要显示的数据的约束和大小,则可以,如果文本长度大于标签的大小,则可能会很好,但无法扩展。第二种方式最终根据要显示的文本的大小设置框架。

参考扩展解决方案:

for(int i=1; i< newLinesToPad; i++) 
    self.text = [self.text stringByAppendingString:@"\n"];

应替换为

for(int i=0; i<newLinesToPad; i++)
    self.text = [self.text stringByAppendingString:@"\n "];

每增加一行换行符都需要额外的空间,因为iPhone UILabels的尾部回车符似乎被忽略了:(

同样,alignBottom也应该用@“\n@%”代替“\n@”进行更新(对于周期初始化,也必须用“for(int i=0…”替换)。

以下扩展适用于我:

// -- file: UILabel+VerticalAlign.h
#pragma mark VerticalAlign
@interface UILabel (VerticalAlign)
- (void)alignTop;
- (void)alignBottom;
@end

// -- file: UILabel+VerticalAlign.m
@implementation UILabel (VerticalAlign)
- (void)alignTop {
    CGSize fontSize = [self.text sizeWithFont:self.font];
    double finalHeight = fontSize.height * self.numberOfLines;
    double finalWidth = self.frame.size.width;    //expected width of label
    CGSize theStringSize = [self.text sizeWithFont:self.font constrainedToSize:CGSizeMake(finalWidth, finalHeight) lineBreakMode:self.lineBreakMode];
    int newLinesToPad = (finalHeight  - theStringSize.height) / fontSize.height;
    for(int i=0; i<newLinesToPad; i++)
        self.text = [self.text stringByAppendingString:@"\n "];
}

- (void)alignBottom {
    CGSize fontSize = [self.text sizeWithFont:self.font];
    double finalHeight = fontSize.height * self.numberOfLines;
    double finalWidth = self.frame.size.width;    //expected width of label
    CGSize theStringSize = [self.text sizeWithFont:self.font constrainedToSize:CGSizeMake(finalWidth, finalHeight) lineBreakMode:self.lineBreakMode];
    int newLinesToPad = (finalHeight  - theStringSize.height) / fontSize.height;
    for(int i=0; i<newLinesToPad; i++)
        self.text = [NSString stringWithFormat:@" \n%@",self.text];
}
@end

然后调用[yourLabel alignTop];或[yourLabel alignBottom];在每次标签文本分配后。