如何从底部对齐 UILabel 文本?

Posted

技术标签:

【中文标题】如何从底部对齐 UILabel 文本?【英文标题】:How to align UILabel text from bottom? 【发布时间】:2013-08-17 08:41:11 【问题描述】:

UILabel 如何从底部对齐。比方说,我的标签可以容纳三行文本。如果输入文本是单行,那么这一行应该在标签的底部。请参考下图更好地理解。橙色区域是标签的全框。目前它只有一条线,并且居中对齐。所以我想要的是,无论有多少行,它都应该始终对齐底部。

请提出你的想法。

谢谢。

【问题讨论】:

【参考方案1】:

将你的 UILabel 放在一个垂直的 UIStackView 中,并用一个虚拟视图作为间隔。 此外,将虚拟视图设​​置为较低的拥抱和压缩优先级。

从上到下:

标签 虚拟视图

自下而上:

虚拟视图 标签

Screenshot

【讨论】:

【参考方案2】:

Swift 4.2 版本使用contentMode 属性设置顶部和底部:

class VerticalAlignedLabel: UILabel 
    
    override func drawText(in rect: CGRect) 
        var newRect = rect
        switch contentMode 
        case .top:
            newRect.size.height = sizeThatFits(rect.size).height
        case .bottom:
            let height = sizeThatFits(rect.size).height
            newRect.origin.y += rect.size.height - height
            newRect.size.height = height
        default:
            ()
        
        
        super.drawText(in: newRect)
    

然后像这样设置你的标签:

let label = VerticalAlignedLabel()
label.contentMode = .bottom

【讨论】:

值得注意的是,这可以与 IB 中的自定义分类 UILabel 无缝协作(在此处设置 contentMode),并且此解决方案不需要 sizeToFit() 这个答案很棒? 如何让界面生成器更新显示标签的位置?这不可能吗? @JamesJoshuaStreet 您可以尝试在类初始化之前添加 (at)IBDesignable 行。将 (at) 替换为 @。更多信息:nshipster.com/ibinspectable-ibdesignable/#ibdesignable 嗯,是的,我有,但它不起作用。也许我编辑了一些重要的东西。我会在星期一再次测试它【参考方案3】:
    使用自动布局)
textLabel.numberOfLines = 0
textLabel.textAlignment = .center

textLabel.topAnchor.constraint(greaterThanOrEqualTo: sView.topAnchor).isActive = true
textLabel.leadingAnchor.constraint(equalTo: sView.leadingAnchor).isActive = true
textLabel.trailingAnchor.constraint(equalTo: sView.trailingAnchor).isActive = true
textLabel.bottomAnchor.constraint(equalTo: sView.bottomAnchor).isActive = true

【讨论】:

【参考方案4】:

我最近遇到了这个问题,并且能够通过将我的标签本身放在堆栈视图中来解决它。我从这个post 得到了这个想法,它有相同的问题但有多个标签。相同的技术可以用于单个标签。

stackview 的轴 = 水平和对齐 = 底部(这就是诀窍)。

我的标签现在与底部完美对齐,这正是我所需要的。

【讨论】:

【参考方案5】:

在 IB 中,正如 @Tobe 所说,对超级视图的底部约束应该起作用, 如果您有多个子视图或水平堆栈视图,其中一个元素具有底部约束,则使用 Layout Margin to be Fixed 底部小于其他边距

【讨论】:

【参考方案6】:

这里有两种方法...

1. 首先将numberOfLines 设置为0,然后使用UILabelsizeToFit 属性,这样您的UILabel 将与其contentSize 一起显示。

yourLabel.numberOfLines = 0;

[yourLabel sizeToFit];

从此链接查看更多信息:Vertically align text within a UILabel

2. 另一种选择是采用UITextField 而不是UILabel 并将userInteractionEnabled 设置为NO,如下所示...

[yourTextField setUserInteractionEnabled:NO];

然后将contentVerticalAlignment 属性设置为底部,如下所示...

[yourTextField setContentVerticalAlignment:UIControlContentVerticalAlignmentBottom];

更新

另外,使用UITextField,我们无法实现多行。因此,我们可以使用UITextView 并将其userInteractionEnabled 设置为NO。然后,使用下面的代码使其底部对齐。

CGFloat topCorrect = ([label bounds].size.height - [label contentSize].height);
topCorrect = (topCorrect <0.0 ? 0.0 : topCorrect);
label.contentOffset = (CGPoint).x = 0, .y = -topCorrect;

【讨论】:

我已经尝试过第一个解决方案。但它不能正常工作。它总是在顶部和左侧对齐。但它应该始终在底部和中心对齐。但第二种解决方案似乎正在奏效。第二个解决方案中的多行呢?有可能吗? 假设这个有 3 行的框架是 CGRectMake(10,100,100,300); 那么如果你只得到一行然后设置这样的框架 CGRectMake(10,260,100,300); ,这里只需设置一些带有逻辑的自定义代码 否则第二个选项是最好的:) 第二个是最好的。我会尽力让你知道的。 您好,我在 UITextView 中实现了相同的概念。它工作完美。谢谢..我已经更新了我在代码中实现的答案。 嗨,你能编辑你的答案吗,所以它最适合我的问题。目前它不完整。【参考方案7】:

我只为 IB 中的超级视图设置了一个底部约束,这对我有用,而无需使用代码以及最大约束的行数。

【讨论】:

【参考方案8】:

您可以继承 UILabel 并覆盖该方法:

- (void)drawTextInRect:(CGRect)rect

使用您要使用的 rect 调用 super drawTextInRect

【讨论】:

你也可以使用 - (CGRect)textRectForBounds:(CGRect)bounds limitedToNumberOfLines:(NSInteger)numberOfLines;这可能更明确。【参考方案9】:

另一种选择:使用一个标签作为背景颜色,我称之为 originalLabel,另一个作为文本标签,在我的示例中称为 textLabel。然后计算textLabel的高度和Y坐标:

[textLabel sizeToFit];
int height = textLabel.frame.size.height;
int yCoord = originalLabel.frame.origin.y + 
          originalLabel.frame.size.height - height;
textLabel.frame = CGRectMake( originalLabel.frame.origin.x, yCoord,
          textLabel.frame.size.width, height);

【讨论】:

【参考方案10】:

我有同样的问题。以下是我如何将文本与 UILabel 底部对齐:

- (void)alignLabel:(UILabel *)l withText:(NSString *)text verticalAlignOption:(int)vertAlign
CGSize stringSize = [text sizeWithFont:l.font constrainedToSize:l.frame.size lineBreakMode:l.lineBreakMode];

switch (vertAlign) 
    case 0: // align = top
        l.frame = CGRectMake(l.frame.origin.x,
                                   l.frame.origin.y,
                                   l.frame.size.width,
                                   stringSize.height
                                   );
        break;
    case 1: // align = bottom
        l.frame = CGRectMake(l.frame.origin.x,
                                   (l.frame.origin.y + l.frame.size.height) - stringSize.height,
                                   l.frame.size.width,
                                   stringSize.height
                                   );
        break;
    case 2: // align = middle
        // default
        break;


l.text = text;

你只需调用这样的方法来对齐底部:

[self alignLabel:self.mediaTitle withText:@"My text to align" verticalAlignOption:1];

【讨论】:

【参考方案11】:

子类 UILabel

@interface Label : UILabel

@end

然后像这样覆盖drawTextInRect

@implementation Label

- (void)drawTextInRect:(CGRect)rect

    if(alignment == top) 

        rect.size.height = [self sizeThatFits:rect.size].height;
    

    if(alignment == bottom) 

        CGFloat height = [self sizeThatFits:rect.size].height;

        rect.origin.y += rect.size.height - height;
        rect.size.height = height;
    

    [super drawTextInRect:rect];


@end

【讨论】:

这实际上对我来说非常有效,几乎不费吹灰之力,而且不像这里的其他一些解决方案那样让人觉得很老套。

以上是关于如何从底部对齐 UILabel 文本?的主要内容,如果未能解决你的问题,请参考以下文章

如何将 UIButton 文本与 UILabel 文本垂直对齐?

强制文本在 UILabel 中垂直居中

如何将 UILabel 文本设置为顶部对齐

如何在 animateWithDuration 的每个动画之间重复更改 UILabel 的文本?

使用 Autolayout 将 UILabel 沿其父视图的底部对齐

如何将 UILabel 文本顶部和底部空间居中