垂直对齐UILabel

时间:2012-06-29 10:16:13

标签: ios xcode uilabel

我正在尝试在我的应用的UILabel视图中垂直对齐文本。问题是我希望文本垂直对齐顶部,标签的大小为280 x 150.我只能实现这两件事之一。如果我删除该行

[myLabel sizeToFit];

然后文本的对齐没问题但是大小搞砸了。但是如果我添加上面的行,那么对齐就搞砸了但是大小没问题。我该如何解决这个问题。

我已添加以下代码 -

CGRect labelFrame = CGRectMake(22, 50, 280, 150);
UILabel *myLabel = [[UILabel alloc] initWithFrame:labelFrame];
[myLabel setText:finalRecipe];
[myLabel setBackgroundColor: [UIColor lightGrayColor]];
[myLabel setNumberOfLines:0];
[myLabel sizeToFit];
[self.view addSubview:myLabel];

10 个答案:

答案 0 :(得分:17)

不要使用UILabel。将UIButtonUserInteractionEnabled = NO;一起使用,其中包含垂直或水平对齐文字的选项。

你走了:

夫特:

btnDetail.titleLabel?.numberOfLines = 5
btnDetail.titleLabel?.lineBreakMode = .byCharWrapping
btnDetail.contentVerticalAlignment = .top
btnDetail.contentHorizontalAlignment = .left
btnDetail.isUserInteractionEnabled = false
btnDetail.autoresizesSubviews = true
btnDetail.autoresizingMask = .flexibleWidth

的OB​​J-C

[btnDetail.titleLabel setNumberOfLines:5];
[btnDetail.titleLabel setLineBreakMode:NSLineBreakByCharWrapping];
[btnDetail setContentVerticalAlignment:UIControlContentVerticalAlignmentTop];
[btnDetail setContentHorizontalAlignment:UIControlContentHorizontalAlignmentLeft];
[btnDetail setUserInteractionEnabled:NO];
btnDetail.autoresizesSubviews = YES;
btnDetail.autoresizingMask = UIViewAutoresizingFlexibleWidth;

答案 1 :(得分:12)

我是FXLabel的作者,虽然我不懂Manish,但我相信他正在努力帮助(如果他是在为我做广告,我当然没有要求他,而且我不付钱他 - 抱歉Manish!)。

FXLabel的一个特性是它尊重标签的UIContentMode属性,如“接口”构建器中所设置的那样。这意味着你可以设置label.contentMode = UIViewContentModeTop;将文本对齐到标签视图的顶部(这对常规UILabel不起作用)。相关的例子在这里:

  

https://github.com/nicklockwood/FXLabel/tree/master/Examples/Text%20Alignment

FXLabel是UILabel的一个子类,所以我认为对于提出的问题来说这是一个非常好的解决方案。但是,如果海​​报宁愿在不使用第三方库的情况下解决问题(这是可以理解的),那么这里是代码:

CGRect labelFrame = CGRectMake(22, 50, 280, 150);
UILabel *myLabel = [[UILabel alloc] initWithFrame:labelFrame];
[myLabel setText:finalRecipe];
[myLabel setBackgroundColor: [UIColor lightGrayColor]];
[myLabel setNumberOfLines:0];

CGFloat fontSize = 0.0f;
labelFrame.size = [myLabel.text sizeWithFont:myLabel.font
                                minFontSize:myLabel.minimumFontSize
                             actualFontSize:&fontSize
                                   forWidth:labelFrame.width
                            lineBreakMode:myLabel.lineBreakMode];

myLabel.frame = labelFrame;
[self.view addSubview:myLabel];

注意:(这是未经测试的,如果有任何拼写错误,请道歉)

答案 2 :(得分:12)

你需要继承UILabel。试试这个:

- (void)drawTextInRect:(CGRect)rect
{
    CGSize sizeThatFits = [self sizeThatFits:rect.size];
    rect.size.height = MIN(rect.size.height, sizeThatFits.height);

    [super drawTextInRect:rect];
}

正如您所发现的,UILabel将文本垂直居中于其范围内。在这里,我们询问-sizeThatFits文本块大小,并使用它来约束传递给UILabel的绘图矩形,以便从标签边界的顶部绘制文本。

你甚至可以像这样支持被忽略的(叹气)contentMode属性:

- (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];
}

这里有许多其他解决方案和讨论:Vertically align text to top within a UILabel

答案 3 :(得分:9)

在Swift中,JRC的子类化UILabel的解决方案,覆盖drawTextInRect并符合UIViewContentMode将如下所示:

class AlignableUILabel: UILabel {

    override func drawText(in rect: CGRect) {

        var newRect = CGRect(x: rect.origin.x,y: rect.origin.y,width: rect.width, height: rect.height)
        let fittingSize = sizeThatFits(rect.size)

        if contentMode == UIViewContentMode.top {
            newRect.size.height = min(newRect.size.height, fittingSize.height)
        } else if contentMode == UIViewContentMode.bottom {
            newRect.origin.y = max(0, newRect.size.height - fittingSize.height)
        }

        super.drawText(in: newRect)
    }

}

实施只是一个问题:

yourLabel.contentMode = UIViewContentMode.top

对我来说,它就像一个魅力。

答案 4 :(得分:1)

有一种没有子类化的方法,使用按钮或自己滚动。

将行数设置为0,然后调用sizeToFit。

[label setNumberOfLines:0];
[label sizeToFit];

此处有更多详细信息,因为我认为有人链接到:Vertically align text to top within a UILabel

答案 5 :(得分:1)

您可以在界面构建器上使用约束来创建它。

  1. 输入您想要的行数
  2. 创建一个约束,其高度足够大,适用于3行和关系部分放置"小于或等于"。
  3. 希望这对你有帮助!

答案 6 :(得分:1)

除了上述建议外,建议将行数设置为0并将换行符设置为自动换行,请确保不指定高度限制。显示的文本会根据需要自动添加新行,并且文本始终垂直对齐标签顶部。

答案 7 :(得分:0)

我通过实施一个类别来实现你想要的目标:

·H

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

的.m

@implementation UILabel (VerticalAlign)

#pragma mark
#pragma mark - Align Methods

- (void)alignTop
{
    [self setFrame:[self newLabelFrame:UIControlContentVerticalAlignmentTop]];
}

- (void)alignBottom
{
    [self setFrame:[self newLabelFrame:UIControlContentVerticalAlignmentBottom]];
}

#pragma mark
#pragma mark - Helper Methods

- (CGRect)newLabelFrame:(UIControlContentVerticalAlignment)alignment
{
    CGRect labelRect = self.frame;

    NSStringDrawingOptions options = NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingTruncatesLastVisibleLine | NSStringDrawingUsesFontLeading;

    CGRect textRect = [self.text boundingRectWithSize:CGSizeMake(227.f, CGFLOAT_MAX)
                                              options:options
                                           attributes:@{NSFontAttributeName:self.font}
                                              context:nil];

    CGFloat textOffset = labelRect.size.height - textRect.size.height;

    UIEdgeInsets contentInsets;
    if (alignment == UIControlContentVerticalAlignmentTop)
    {
        if (textOffset < (labelRect.size.height/2.f))
        {
            contentInsets = UIEdgeInsetsMake(-textOffset, 0.f, 0.f, 0.f);
        }
        else
        {
            contentInsets = UIEdgeInsetsMake(0.f, 0.f, textOffset, 0.f);
        }
    }
    else
    {
        if (textOffset < (labelRect.size.height/2.f))
        {
            contentInsets = UIEdgeInsetsMake(0.f, 0.f, -textOffset, 0.f);
        }
        else
        {
            contentInsets = UIEdgeInsetsMake(textOffset, 0.f, 0.f, 0.f);
        }
    }

    return UIEdgeInsetsInsetRect(labelRect, contentInsets);
}

@end

请记住,您需要设置&#34; NumberOfLines&#34;此示例适用于多行选项!

实施上述类别后,您只需执行以下操作:

[myLabel setText:finalRecipe];
[myLabel alignTop];

干杯!

答案 8 :(得分:0)

好黑客... 我的迅捷4.2 / 5的2美分:

self.optTextMessage.numberOfLines =  0
self.optTitle.lineBreakMode  = .byWordWrapping

并根据建议添加\ n ..

答案 9 :(得分:-2)

您可以按照以下方式执行此操作.......

  1. 从IB

  2. 设置标签的numberOfLines属性0
  3. 将您的标签lineBreakMode设为UILineBreakModeWordWrap非常非常重要

  4. 现在无论你在标签上设置什么,只需要附加几个@“\ n”就可以了...... 离.-

    [yourTextLabel setText:@"myLabel\n\n\n\n\n"];