顶部对齐的UILabel,使文本粘在标签视图的顶部 -iOS

30

有没有一种方法可以使UILabel“顶部对齐”,即使文本粘在标签视图的顶部?与默认的垂直居中对齐或漂浮在视图的中心相反。

这是三个标签的图像,左对齐、右对齐和居中对齐,以及一个UITextView,它是居中和顶部对齐的。无论视图的垂直大小如何,textView的文本都会粘在顶部。我能用标签做同样的事情吗?

输入图片说明


这是我对类似问题给出的答案:https://dev59.com/znNA5IYBdhLWcg3wL62x#1054681 - nevan king
这个链接对我很有用。感谢 nevan king!任何和我有相同问题的人可以访问上面的链接,或者查看我的答案,我认为你们会找到解决方案。 - OWolf
1
快速技巧...只需sizeToFit - Fattie
8个回答

39

有一个解决方法:

  1. 对您的 UILabel 设置高度和宽度 约束(constraint),常量必须小于或等于您想要的最大高度 | 宽度。
  2. 行数(number of lines) 设置为零。
  3. storyboard 中将高度设置为仅适合一行。
  4. 在设置完 UILabel 的文本后,在您的代码中调用 sizeToFit

这将使您的 UILabel 在您想要的最大宽度和高度之间重新调整大小,文本始终保持顶部对齐。


同时,将高度的约束条件设置为 >= 原始高度,将允许标签增长并保持在容器中的左上角与文本一起。 - TomG103
在使用 UICollectionViewCell 时遇到了这个问题。常规的 sizeToFit 方法无法正常工作。您提出的自动布局建议在这种情况下起了作用。谢谢! - Mark Suman
1
感谢您的帖子,对于那些想知道的人,在iOS 11上它运行得非常好 :) - Remy San
请确保使用 <= 而不仅仅是将值设置为小于最大高度。我之前没有理解这一点,但现在它可以正常工作了。 - MrAn3
你是指步骤1和步骤3是什么意思? - MRizwan33
显示剩余2条评论

12
我使用了上面链接中nevan king在我的问题的评论中提供的答案:如何在UILabel中垂直顶部对齐文本 我使用的代码在这里:
- (void)setUILabelTextWithVerticalAlignTop:(NSString *)theText {
    CGSize labelSize = CGSizeMake(250, 300);
    CGSize theStringSize = [theText sizeWithFont:targetLabel.font constrainedToSize:labelSize lineBreakMode:targetLabel.lineBreakMode];
    targetLabel.frame = CGRectMake(targetLabel.frame.origin.x, targetLabel.frame.origin.y, theStringSize.width, theStringSize.height);
    targetLabel.text = theText;
}

//linked to a button that sets the text from a UITextView to the label.
- (IBAction)setText:(id)sender {

    [sourceText resignFirstResponder];
    [self setUILabelTextWithVerticalAlignTop:sourceText.text];
    [targetLabel setNumberOfLines:0];
    [targetLabel sizeToFit];

}

这是项目:

owolf.net/uploads/StackOverflow/verticalAlignUILabel.zip


使用iOS 11代码更新后,对我有效:`UILabel *iconLabel = [UILabel.alloc initWithFrame:CGRectMake(0, 0, size, size)]; [iconLabel setTextColor:[UIColor whiteColor]]; [iconLabel setTextAlignment:NSTextAlignmentCenter]; CGSize labelSize = iconLabel.frame.size; iconLabel.frame = [icon boundingRectWithSize:labelSize options:NSStringDrawingUsesLineFragmentOrigin attributes:nil context:nil];[iconLabel setText:icon]; [iconLabel setNumberOfLines:1]; [iconLabel sizeToFit]; return iconLabel;` - BuguiBu

10
在iOS中,默认情况下无法设置UILabel的垂直对齐方式。相反,您将需要使用NSString提供的sizeWithFont方法之一。使用哪个取决于您是否需要多行或单行标签。对于单行标签可以使用sizeWithFont:forWidth:lineBreakMode:,而对于多行标签可以使用sizeWithFont:constrainedToSize:lineBreakMode:。您可以轻松地使用相关标签的font属性加载字体参数。您可以在这里查看有关使用这些函数的更多详细信息。
这些方法将返回一个CGSize结构体,其中包含基于NSString文本的标签的最小大小。一旦您获得了标签的正确尺寸,您就可以轻松地将其放置在父视图的顶部,并且它将出现为顶部对齐。

3
您可以在标签上调用sizeToFit方法,以使标签的大小适应其内容。 - James P

7

我已经用UITextView替换了UILabel,因为在UITextView中,文本会粘附在顶部。

只是一个建议,可能对某些人有用。


对我很有用 :) 但是如何使它变成多行呢?我似乎找不到允许这样做的选项 :/ - Byron Coetsee
是的,它可以工作,但请告诉我如何更改它的字体大小。我在自定义单元格中有我的TextView。 - mars

1
创建一个UILabel的子类。
.h文件:
@property (nonatomic, assign) UIControlContentVerticalAlignment verticalAlignment;

.m文件

- (void) drawTextInRect:(CGRect)rect 
{
    if(_verticalAlignment == UIControlContentVerticalAlignmentTop ||  _verticalAlignment == UIControlContentVerticalAlignmentBottom)    
    {
         // If one line, we can just use the lineHeight, faster than querying sizeThatFits
         const CGFloat height = floorf(((self.numberOfLines == 1) ? ceilf(self.font.lineHeight) : [self sizeThatFits:self.frame.size].height));
          rect.origin.y = floorf(((self.frame.size.height - height) / 2.0f) * ((_verticalAlignment == UIControlContentVerticalAlignmentTop) ? -1.0f : 1.0f));
    }
    [super drawTextInRect:rect];
}


- (void) setVerticalAlignment:(UIControlContentVerticalAlignment)newVerticalAlignment
{
     _verticalAlignment = newVerticalAlignment;
     [self setNeedsDisplay];
}

我用这个来进行垂直对齐。


1

如果标签的高度不需要保持一致,有一个简单的解决方案:将你的Label放在Stack View中。确保为Stack View添加前导和尾随常量。 以下是在Storyboard中如何操作的截图:

enter image description here


0
在我的应用程序中,我所做的是将UILabel的行属性设置为0,并创建一个底部约束的UILabel,并确保它被设置为>= 0,如下图所示。

enter image description here


0
我的问题出在collectionviewCell上,我想让我的标签包含我设置的文本并顶部对齐,所以我找到了一个解决方法,就是先取一个,将其高度和宽度设置为collectionviewcontentview的高度和宽度,然后将我的imageview和标签添加到中。我设置了图像视图的高度和宽度,对于标签,我只给了尾随、前导和顶部。

My collectionview


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接