ios uilabel 垂直居中_iOS – 让UILabel的文字顶部对齐[转载]

在iOS开发中,UILabel是常用的控件。当内容少时,文字默认靠左垂直对齐。本文介绍了五种实现UILabel文字顶部对齐的方法:1) 使用`sizeToFit`;2) 添加换行符` `;3) 用UITextField替代;4) 重写`drawTextInRect:`;5) 自定义UILabel分类。针对不同场景,开发者可以选择合适的方法。
摘要由CSDN通过智能技术生成

在iOS开发中,用的最多的一个控件非UILabel莫属了。

之前在tableview的自定义不等高的cell时候用过cell的一些较为复杂的应用了。

在日常的开发中会发现,如果UILabel高度有多行,当内容少的时候,那么文字就会默认靠左垂直对齐,如下图:

所以我就有了将文字顶部对齐的需求: stackoverflow.com 上提供了几种方法来达到顶部对齐的效果。

方法一

在显示文字时,用sizeToFit修改Label的高度

[label sizeToFit] ;

如果内容长度超过一行,把numberOfLines设成 0(就是不限制行数)。

有一个问题是,不管你设置了文字是水平居中还是右对齐,那么执行完sizeToFit后 frame 宽度也缩小了,文字会缩到左上角,效果都比较差,如图:

方法二

此方法更加简单粗暴,但是很有效。其方法是在文本后面加多一些\n。

需要注意的是,\n后还得加至少一个空格,否则多余的\n会被UILabel忽略。从这一点上看,UILabel似乎又过于“聪明”了。是把UILabel的 “line break mode” 设为 “Clip”,然后直接在末尾加一些换行符

该方法的示意图如下:

该方法的代码如下:

label.lineBreakMode = UILineBreakModeClip;

label.text = [displayString stringByAppendingString:"\n\n\n\n"];

不过,这个方法不是万能的,当Label文字超出范围并且需要在末尾显示“…”就不行了,不会自动缩略末尾变成“…”。

方法三

用UITextField代替UILabel

用UITextField取代UILabel,默认就是顶端对齐的。

同时把userInterationEnabled设为NO,让它不能滚动。

方法四

重写UILabel的drawTextInRect:方法

创建一个UILabel的子类,用起来非常方便:

// TopLeftLabel.h

#import

@interface TopLeftLabel : UILabel {

}

@end

// TopLeftLabel.m

#import "TopLeftLabel.h"

@implementation TopLeftLabel

- (id)initWithFrame:(CGRect)frame {

return [super initWithFrame:frame];

}

- (CGRect)textRectForBounds:(CGRect)bounds limitedToNumberOfLines:(NSInteger)numberOfLines {

CGRect textRect = [super textRectForBounds:bounds limitedToNumberOfLines:numberOfLines];

textRect.origin.y = bounds.origin.y;

return textRect;

}

-(void)drawTextInRect:(CGRect)requestedRect {

CGRect actualRect = [self textRectForBounds:requestedRect limitedToNumberOfLines:self.numberOfLines];

[super drawTextInRect:actualRect];

}

@end

方法五:

自定义UILabel的分类

#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];

[myLabel alignBottom];

实现

在本项目中,使用第一种方式,一句代码就解决了问题!因为撸主是使用xib来做cell,一开始写在了layoutSubviews方法中

- (void)layoutSubviews{

[super layoutSubviews];

[self.captionLabel sizeToFit];

[self.containerView clipsToCornerRadius:8];

}

但是,出现了第二次滑动到指定位置才有效,并且有奇奇怪怪的效果??

考虑到是cell的重用缓存,以及view的生命周期顺序问题:layoutSubviews方法调用先于drawRect

我要在View绘制子控件时再次确定cell的布局,于是把代码放到drawRect中:

- (void)drawRect:(CGRect)rect{

[self.captionLabel sizeToFit];

[self.containerView clipsToCornerRadius:8];

}

如果还是有问题,可以考虑直接用其他方式,如后来出现有UILabel文字显示不全的现象,最后用方法二代替了~

一起进步~共勉❤️

转载时请注明出处及相应链接,本文永久地址:https://blog.yayuanzi.com/25034.html

微信打赏

支付宝打赏

感谢您对作者Annwn的打赏,我们会更加努力!    如果您想成为作者,请点我

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值