我有一个UILabel,它有两行文字的空间。有时,当文本太短时,此文本会显示在标签的垂直中心。
如何垂直对齐文本,使其始终位于UILabel的顶部?
我有一个UILabel,它有两行文字的空间。有时,当文本太短时,此文本会显示在标签的垂直中心。
如何垂直对齐文本,使其始终位于UILabel的顶部?
当前回答
如果您使用的是自动布局,请在代码或IB中将垂直内容HuggingPriority设置为1000。在IB中,您可能需要通过将其优先级设置为1然后删除来删除高度限制。
其他回答
快速用户界面
在SwiftUI中,所有视图的大小通常为适合其内容的大小,但如果明确使用框架修饰符,则可以使用框架的对齐参数:
Text("Text")
.background(Color.red)
.frame(width: 100, height: 200, alignment: .top)
此外,如果使用任何类型的“堆栈”来排列视图,所有视图都有一个类似于框架的参数,称为对齐:
ZStack(alignment: .top) {
Color.red
Text("Text")
.background(Color.red)
}
创建新类
标签顶部对齐
.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
我在应用程序中所做的是将UILabel的line属性设置为0,并创建UILabel的底部约束,并确保其设置为>=0,如下图所示。
我花了一段时间阅读了代码,以及介绍页面中的代码,发现它们都试图修改标签的框架大小,这样就不会出现默认的中心垂直对齐。
然而,在某些情况下,我们确实希望标签占据所有这些空间,即使标签确实有太多文本(例如,高度相等的多行)。
在这里,我使用了另一种方法来解决这个问题,只需在标签末尾添加换行符(请注意,我实际上继承了UILabel,但这不是必须的):
CGSize fontSize = [self.text sizeWithFont:self.font];
finalHeight = fontSize.height * self.numberOfLines;
finalWidth = 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 "];
}
我重复了戴莱辛的建议,并添加了一个UIEdgeInset,以允许调整边距。周围环境不错。
- (id)init
{
if (self = [super init]) {
contentEdgeInsets = UIEdgeInsetsZero;
}
return self;
}
- (void)layoutSubviews
{
CGRect localBounds = self.bounds;
localBounds = CGRectMake(MAX(0, localBounds.origin.x + contentEdgeInsets.left),
MAX(0, localBounds.origin.y + contentEdgeInsets.top),
MIN(localBounds.size.width, localBounds.size.width - (contentEdgeInsets.left + contentEdgeInsets.right)),
MIN(localBounds.size.height, localBounds.size.height - (contentEdgeInsets.top + contentEdgeInsets.bottom)));
for (UIView *subview in self.subviews) {
if ([subview isKindOfClass:[UILabel class]]) {
UILabel *label = (UILabel*)subview;
CGSize lineSize = [label.text sizeWithFont:label.font];
CGSize sizeForText = [label.text sizeWithFont:label.font constrainedToSize:localBounds.size lineBreakMode:label.lineBreakMode];
NSInteger numberOfLines = ceilf(sizeForText.height/lineSize.height);
label.numberOfLines = numberOfLines;
label.frame = CGRectMake(MAX(0, contentEdgeInsets.left), MAX(0, contentEdgeInsets.top), localBounds.size.width, MIN(localBounds.size.height, lineSize.height * numberOfLines));
}
}
}