我有一个UILabel,它有两行文字的空间。有时,当文本太短时,此文本会显示在标签的垂直中心。
如何垂直对齐文本,使其始终位于UILabel的顶部?
我有一个UILabel,它有两行文字的空间。有时,当文本太短时,此文本会显示在标签的垂直中心。
如何垂直对齐文本,使其始终位于UILabel的顶部?
当前回答
我重复了戴莱辛的建议,并添加了一个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));
}
}
}
其他回答
参考扩展解决方案:
for(int i=1; i< newLinesToPad; i++)
self.text = [self.text stringByAppendingString:@"\n"];
应替换为
for(int i=0; i<newLinesToPad; i++)
self.text = [self.text stringByAppendingString:@"\n "];
每增加一行换行符都需要额外的空间,因为iPhone UILabels的尾部回车符似乎被忽略了:(
同样,alignBottom也应该用@“\n@%”代替“\n@”进行更新(对于周期初始化,也必须用“for(int i=0…”替换)。
以下扩展适用于我:
// -- file: UILabel+VerticalAlign.h
#pragma mark VerticalAlign
@interface UILabel (VerticalAlign)
- (void)alignTop;
- (void)alignBottom;
@end
// -- file: UILabel+VerticalAlign.m
@implementation UILabel (VerticalAlign)
- (void)alignTop {
CGSize fontSize = [self.text sizeWithFont:self.font];
double finalHeight = fontSize.height * self.numberOfLines;
double finalWidth = self.frame.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 "];
}
- (void)alignBottom {
CGSize fontSize = [self.text sizeWithFont:self.font];
double finalHeight = fontSize.height * self.numberOfLines;
double finalWidth = self.frame.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 = [NSString stringWithFormat:@" \n%@",self.text];
}
@end
然后调用[yourLabel alignTop];或[yourLabel alignBottom];在每次标签文本分配后。
您可以通过代码或简单地在故事板上执行以下操作来解决此问题:
将UILabel的行数设置为0。将UILabel嵌入UIView中。设置UIView约束(顶部、右侧、左侧和底部),以占用UILabel应增长到的最大空间。然后将UILabel设置为UIView的顶部、右侧和左侧,并将约束设置为底部,距离>=0。
使用textRect(对于边界:limitedToNumberOfLines:)。
class TopAlignedLabel: UILabel {
override func drawText(in rect: CGRect) {
let textRect = super.textRect(forBounds: bounds, limitedToNumberOfLines: numberOfLines)
super.drawText(in: textRect)
}
}
就像上面的答案一样,但它不太正确,或者很容易插入代码,所以我稍微清理了一下。将此扩展名添加到它自己的.h和.m文件中,或者直接粘贴到您打算使用的实现上方:
#pragma mark VerticalAlign
@interface UILabel (VerticalAlign)
- (void)alignTop;
- (void)alignBottom;
@end
@implementation UILabel (VerticalAlign)
- (void)alignTop
{
CGSize fontSize = [self.text sizeWithFont:self.font];
double finalHeight = fontSize.height * self.numberOfLines;
double finalWidth = self.frame.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"];
}
}
- (void)alignBottom
{
CGSize fontSize = [self.text sizeWithFont:self.font];
double finalHeight = fontSize.height * self.numberOfLines;
double finalWidth = self.frame.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 = [NSString stringWithFormat:@" \n%@",self.text];
}
}
@end
然后要使用,请将文本放入标签中,然后调用适当的方法将其对齐:
[myLabel alignTop];
or
[myLabel alignBottom];
在UILabel中,无法垂直对齐文本。但是,您可以使用NSString的sizeWithFont:方法动态更改标签的高度,并根据需要设置其x和y。
您可以使用UITextField。它支持contentVerticalAlignment人员,因为它是UIControl的子类。您必须将其userInteractionEnabled设置为NO,以防止用户在其上键入文本。