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

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


当前回答

不要大惊小怪

@interface MFTopAlignedLabel : UILabel

@end


@implementation MFTopAlignedLabel

- (void)drawTextInRect:(CGRect) rect
{
    NSAttributedString *attributedText = [[NSAttributedString alloc]     initWithString:self.text attributes:@{NSFontAttributeName:self.font}];
    rect.size.height = [attributedText boundingRectWithSize:rect.size
                                            options:NSStringDrawingUsesLineFragmentOrigin
                                            context:nil].size.height;
    if (self.numberOfLines != 0) {
        rect.size.height = MIN(rect.size.height, self.numberOfLines * self.font.lineHeight);
    }
    [super drawTextInRect:rect];
}

@end

没有混乱,没有Objective-c,没有大惊小怪,只有Swift 3:

class VerticalTopAlignLabel: UILabel {

    override func drawText(in rect:CGRect) {
        guard let labelText = text else {  return super.drawText(in: rect) }

        let attributedText = NSAttributedString(string: labelText, attributes: [NSFontAttributeName: font])
        var newRect = rect
        newRect.size.height = attributedText.boundingRect(with: rect.size, options: .usesLineFragmentOrigin, context: nil).size.height

        if numberOfLines != 0 {
            newRect.size.height = min(newRect.size.height, CGFloat(numberOfLines) * font.lineHeight)
        }

        super.drawText(in: newRect)
    }

}

雨燕4.2

class VerticalTopAlignLabel: UILabel {

    override func drawText(in rect:CGRect) {
        guard let labelText = text else {  return super.drawText(in: rect) }

        let attributedText = NSAttributedString(string: labelText, attributes: [NSAttributedString.Key.font: font])
        var newRect = rect
        newRect.size.height = attributedText.boundingRect(with: rect.size, options: .usesLineFragmentOrigin, context: nil).size.height

        if numberOfLines != 0 {
            newRect.size.height = min(newRect.size.height, CGFloat(numberOfLines) * font.lineHeight)
        }

        super.drawText(in: newRect)
    }

}

其他回答

如果可以选择创建自己的自定义视图,可以执行以下操作:

- (void)drawRect:(CGRect)rect
{
    CGRect bounds = self.bounds;
    [self.textColor set];
    [self.text drawInRect:bounds
                 withFont:self.font
            lineBreakMode:UILineBreakModeTailTruncation
                alignment:self.textAlignment];
}

试试这个!!太手动了,但对我来说很完美。

[labelName setText:@"This is just a demo"];

NSMutableString *yourString1= @"This is just a demo";


// breaking string
labelName.lineBreakMode=UILineBreakModeTailTruncation;
labelName.numberOfLines = 3;


CGSize maximumLabelSize1 = CGSizeMake(276,37); // Your Maximum text size

CGSize expectedLabelSize1 = [yourString1 sizeWithFont:labelName.font
                                    constrainedToSize:maximumLabelSize1
                                        lineBreakMode:labelName.lineBreakMode];

[labelName setText:yourString1];


CGRect newFrame1 = labelName.frame;
if (expectedLabelSize1.height>=10)
{
    newFrame1.size.height = expectedLabelSize1.height;
}

labelName.frame = newFrame1;

对于Adaptive UI(iOS8或更高版本),要通过更改财产从StoryBoard设置UILabel的垂直对齐noOfLines=0`和

限制条件调整UILabel LefMargin、RightMargin和Top Margin约束。更改垂直=1000的内容压缩阻力优先级,使垂直>水平。

编辑日期:

noOfLines=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()
}

这解决了我的问题。