最新消息:文章中包含代码时,请遵守代码高亮规范!

iOS – 让UILabel的文字顶部对齐[转载]

iOS 石, 稳 155浏览 0评论

转自博客:https://blog.csdn.net/u013316626/article/details/71059601

转自博客:http://blog.devtang.com/2011/11/20/set-uilabel-text-align-top/

在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 <Foundation/Foundation.h>
@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.csdn.net/u013316626/article/details/71059601

转自博客:http://blog.devtang.com/2011/11/20/set-uilabel-text-align-top/

一起进步~共勉❤️

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


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

您必须 登录 才能发表评论!