我有一个UILabel,它有两行文字的空间。有时,当文本太短时,此文本会显示在标签的垂直中心。
如何垂直对齐文本,使其始终位于UILabel的顶部?
我有一个UILabel,它有两行文字的空间。有时,当文本太短时,此文本会显示在标签的垂直中心。
如何垂直对齐文本,使其始终位于UILabel的顶部?
当前回答
如果可以选择创建自己的自定义视图,可以执行以下操作:
- (void)drawRect:(CGRect)rect
{
CGRect bounds = self.bounds;
[self.textColor set];
[self.text drawInRect:bounds
withFont:self.font
lineBreakMode:UILineBreakModeTailTruncation
alignment:self.textAlignment];
}
其他回答
我知道这是一篇旧文章,但垂直对齐文本是一个巨大的问题(至少对我来说是这样),我想我应该分享这个解决方案,因为我自己找不到。
在我看来,使用drawRect有点贵。使UILabel垂直对齐的正确方法是不使用UILabel。使用UITextView(多行UITextField)并观察内容属性,如下所示:
- (UITextView*)textView{
if(!_textView){
UIEdgeInsets insets = UIEdgeInsetsMake(0, 50, 0, 5);
CGRect frame = CGRectMake(0.0f, 0.0f, 100.0f, 100.0f);
_textView = [[UITextView alloc]initWithFrame:UIEdgeInsetsInsetRect(frame, insets)];
_textView.delegate = self;
_textView.scrollEnabled = YES;
_textView.bounces = YES;
_textView.backgroundColor = [UIColor whiteColor];
[_textView setUserInteractionEnabled:NO];
[_textView addObserver:self forKeyPath:@"contentSize" options:(NSKeyValueObservingOptionNew) context:NULL];
}
return _textView;
}
-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change: (NSDictionary *)change context:(void *)context {
UITextView *tv = object;
CGFloat height = [tv bounds].size.height;
CGFloat contentheight;
#ifdef __IPHONE_7_0
contentheight = [tv sizeThatFits:CGSizeMake(tv.frame.size.width, FLT_MAX)].height;
#else
contentheight = [tv contentSize].height;
#endif
switch(self.verticalAlignment) {
case VerticalAlignmentBottom:{
CGFloat topCorrect = ([tv bounds].size.height - contentheight);
topCorrect = (topCorrect <0.0 ? 0.0 : topCorrect);
tv.contentOffset = (CGPoint){.x = 0, .y = -topCorrect};
}
break;
case VerticalAlignmentMiddle:{
CGFloat topCorrect = (height - contentheight * [tv zoomScale])/2.0;
topCorrect = ( topCorrect < 0.0 ? 0.0 : topCorrect );
tv.contentOffset = (CGPoint){.x = 0, .y = -topCorrect};
}
break;
case VerticalAlignmentTop:{
tv.contentOffset = (CGPoint){.x = 0, .y = 0 };
}
break;
default:
break;
}
}
基本上,这里发生的是我们将我们所处的类设置为观察者,使用NSKeyValueObservingOptionNew选项查看contentSize属性,因此每次内容更改时,都会调用-(void)observeValueForKeyPath:ofObject:change:context:,然后您可以计算偏移量大小以适当对齐文本。
我不能把这归功于此,最初的想法来自这里。但是,该解决方案在iOS7上不起作用。在SO周围转了几个小时后,我发现了这个:iOS 7垂直对齐修复。其中的关键行是contentheight=[tv sizeThatFits:CGSizeMake(tv.frame.size.width,FLT_MAX)].height;。由于某种原因,在iOS 7中,获取contentSize高度不起作用,但这可以解决问题。这两个解决方案都不能单独工作,但经过一点修改后,我能够将上述解决方案合成在一起。
子类UILabel并约束绘图矩形,如下所示:
- (void)drawTextInRect:(CGRect)rect
{
CGSize sizeThatFits = [self sizeThatFits:rect.size];
rect.size.height = MIN(rect.size.height, sizeThatFits.height);
[super drawTextInRect:rect];
}
我尝试了涉及换行填充的解决方案,在某些情况下遇到了错误的行为。根据我的经验,如上所述约束绘图矩形比使用numberOfLines更容易。
P.S.你可以想象一下这样轻松地支持UIViewContentMode:
- (void)drawTextInRect:(CGRect)rect
{
CGSize sizeThatFits = [self sizeThatFits:rect.size];
if (self.contentMode == UIViewContentModeTop) {
rect.size.height = MIN(rect.size.height, sizeThatFits.height);
}
else if (self.contentMode == UIViewContentModeBottom) {
rect.origin.y = MAX(0, rect.size.height - sizeThatFits.height);
rect.size.height = MIN(rect.size.height, sizeThatFits.height);
}
[super drawTextInRect:rect];
}
我已经使用了上面的很多方法,只是想添加一个快速而肮脏的方法:
myLabel.text = [NSString stringWithFormat:@"%@\n\n\n\n\n\n\n\n\n",@"My label text string"];
确保字符串中的换行数将导致任何文本填充可用的垂直空间,并将UILabel设置为截断任何溢出的文本。
因为有时候足够好就是足够好。
yourLabel.baselineAdjustment = UIBaselineAdjustmentAlignCenters;
对于那些使用自定义表单元格试图解决此问题的人,请将其添加到自定义表单元格类中:
斯威夫特2.2:
override func layoutSubviews() {
labelName.sizeToFit()
}
这解决了我的问题。