我有一个UILabel,它有两行文字的空间。有时,当文本太短时,此文本会显示在标签的垂直中心。
如何垂直对齐文本,使其始终位于UILabel的顶部?
我有一个UILabel,它有两行文字的空间。有时,当文本太短时,此文本会显示在标签的垂直中心。
如何垂直对齐文本,使其始终位于UILabel的顶部?
当前回答
对于Swift 3。。。
@IBDesignable class TopAlignedLabel: UILabel {
override func drawText(in rect: CGRect) {
if let stringText = text {
let stringTextAsNSString = stringText as NSString
let labelStringSize = stringTextAsNSString.boundingRect(with: CGSize(width: self.frame.width,height: CGFloat.greatestFiniteMagnitude),
options: NSStringDrawingOptions.usesLineFragmentOrigin,
attributes: [NSFontAttributeName: font],
context: nil).size
super.drawText(in: CGRect(x:0,y: 0,width: self.frame.width, height:ceil(labelStringSize.height)))
} else {
super.drawText(in: rect)
}
}
override func prepareForInterfaceBuilder() {
super.prepareForInterfaceBuilder()
layer.borderWidth = 1
layer.borderColor = UIColor.black.cgColor
}
}
其他回答
我接受了这里的建议,并创建了一个可以包装UILabel的视图,它将调整大小并设置行数,使其顶部对齐。只需将UILabel作为子视图:
@interface TopAlignedLabelContainer : UIView
{
}
@end
@implementation TopAlignedLabelContainer
- (void)layoutSubviews
{
CGRect bounds = self.bounds;
for (UILabel *label in [self subviews])
{
if ([label isKindOfClass:[UILabel class]])
{
CGSize fontSize = [label.text sizeWithFont:label.font];
CGSize textSize = [label.text sizeWithFont:label.font
constrainedToSize:bounds.size
lineBreakMode:label.lineBreakMode];
label.numberOfLines = textSize.height / fontSize.height;
label.frame = CGRectMake(0, 0, textSize.width,
fontSize.height * label.numberOfLines);
}
}
}
@end
创建新类
标签顶部对齐
.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
使用故事板最简单的方法:
在StackView中嵌入标签,并在属性检查器中设置StackView的以下两个属性:
1-轴到水平,
2-与顶部对齐
在发布的所有其他解决方案的基础上,我创建了一个简单的小UILabel子类,在设置其对齐属性时将为您处理垂直对齐。这还将在方向更改时更新标签,将高度约束到文本,并将标签的宽度保持在其原始大小。
.h
@interface VAlignLabel : UILabel
@property (nonatomic, assign) WBZVerticalAlignment alignment;
@end
.m
-(void)setAlignment:(WBZVerticalAlignment)alignment{
_alignment = alignment;
CGSize s = [self.text sizeWithFont:self.font constrainedToSize:CGSizeMake(self.frame.size.width, 9999) lineBreakMode:NSLineBreakByWordWrapping];
switch (_alignment)
{
case wbzLabelAlignmentVerticallyTop:
self.frame = CGRectMake(self.frame.origin.x, self.frame.origin.y, self.frame.size.width, s.height);
break;
case wbzLabelAlignmentVerticallyMiddle:
self.frame = CGRectMake(self.frame.origin.x, self.frame.origin.y + (self.frame.size.height - s.height)/2, self.frame.size.width, s.height);
break;
case wbzLabelAlignmentVerticallyBottom:
self.frame = CGRectMake(self.frame.origin.x, self.frame.origin.y + (self.frame.size.height - s.height), self.frame.size.width, s.height);
break;
default:
break;
}
}
-(void)layoutSubviews{
[self setAlignment:self.alignment];
}
不要大惊小怪
@interface MFTopAlignedLabel : UILabel
@end
@implementation MFTopAlignedLabel
- (void)drawTextInRect:(CGRect) rect
{
NSAttributedString *attributedText = [[NSAttributedString alloc] initWithString:self.text attributes:@{NSFontAttributeName:self.font}];
rect.size.height = [attributedText boundingRectWithSize:rect.size
options:NSStringDrawingUsesLineFragmentOrigin
context:nil].size.height;
if (self.numberOfLines != 0) {
rect.size.height = MIN(rect.size.height, self.numberOfLines * self.font.lineHeight);
}
[super drawTextInRect:rect];
}
@end
没有混乱,没有Objective-c,没有大惊小怪,只有Swift 3:
class VerticalTopAlignLabel: UILabel {
override func drawText(in rect:CGRect) {
guard let labelText = text else { return super.drawText(in: rect) }
let attributedText = NSAttributedString(string: labelText, attributes: [NSFontAttributeName: font])
var newRect = rect
newRect.size.height = attributedText.boundingRect(with: rect.size, options: .usesLineFragmentOrigin, context: nil).size.height
if numberOfLines != 0 {
newRect.size.height = min(newRect.size.height, CGFloat(numberOfLines) * font.lineHeight)
}
super.drawText(in: newRect)
}
}
雨燕4.2
class VerticalTopAlignLabel: UILabel {
override func drawText(in rect:CGRect) {
guard let labelText = text else { return super.drawText(in: rect) }
let attributedText = NSAttributedString(string: labelText, attributes: [NSAttributedString.Key.font: font])
var newRect = rect
newRect.size.height = attributedText.boundingRect(with: rect.size, options: .usesLineFragmentOrigin, context: nil).size.height
if numberOfLines != 0 {
newRect.size.height = min(newRect.size.height, CGFloat(numberOfLines) * font.lineHeight)
}
super.drawText(in: newRect)
}
}