深入浅出iOS征服iOSiOS Developer

iOS开发-UILabel高度计算(text、attribute

2017-06-25  本文已影响403人  life白玉兰

做iOS开发的小伙伴们,肯定对UILabel这样的基础控件了解很深,也一定对label显示文本内容的宽高计算,尤其是多行带行间距的情况下有时会感到头痛,每个人都有自己的计算方法,有些或许比较雷同,最近做项目遇到的多行带行间距的情况较多,这两天想了一个以前未曾用过的方法,其实也没太大的新意,分享出来给大家看看,希望对有需要的同学有帮助。

OK,我先介绍下我用到的小工具:

#import@interface UILabel (YGZExt)

@property (nonatomic, readonly) CGFloat lineHeight;     //文本单行高度

@property (nonatomic, readonly) NSInteger textNumberOfLines;   //文本实际行数

@property (nonatomic, readonly) CGFloat textHeight;    //文本实际高度

@property (nonatomic, readonly) CGFloat textWidth;     //文本实际宽度

- (CGSize)textSizeForLimitedSize:(CGSize)size;

- (NSMutableAttributedString *)attributedStringWith:(NSString *)string lineSpace:(CGFloat)lineSpace limitWidth:(CGFloat)limitWidth;

@end

下面看具体实现:

#import "UILabel+YGZExt.h"

#import "UIView+YGZExt.h"

@implementation UILabel (YGZExt)

- (CGFloat)lineHeight {

CGSize rowSize = [@"单行" sizeWithAttributes:[NSDictionary dictionaryWithObjectsAndKeys:self.font, NSFontAttributeName, nil]];

return rowSize.height;

}

- (NSInteger)textNumberOfLines {

CGSize contentSize = [self.text boundingRectWithSize:CGSizeMake(self.width, 10000) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName:self.font} context:nil].size;

return contentSize.height / self.lineHeight;

}

- (CGFloat)textHeight {

CGSize size = [self textRectForBounds:CGRectMake(0, 0, self.width, 10000) limitedToNumberOfLines:self.numberOfLines].size;

return size.height;

}

- (CGFloat)textWidth {

CGSize size = [self textRectForBounds:CGRectMake(0, 0, self.width, 10000) limitedToNumberOfLines:self.numberOfLines].size;

return size.width;

}

- (CGSize)textSizeForLimitedSize:(CGSize)size {

CGRect rect = CGRectMake(self.frame.origin.x, self.frame.origin.y, size.width, size.height);

self.frame = rect;

CGFloat height = self.textHeight > size.height ? size.height : self.textHeight;

return CGSizeMake(self.textWidth, height);

}

- (NSMutableAttributedString *)attributedStringWith:(NSString *)string lineSpace:(CGFloat)lineSpace limitWidth:(CGFloat)limitWidth {

if (string == nil) {

string = @"";

}

self.width = limitWidth;

self.text = string;

lineSpace = self.textNumberOfLines > 1 ? lineSpace : 0;

NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:string];

NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];

paragraphStyle.lineSpacing = lineSpace; // 调整行间距

NSRange range = NSMakeRange(0, [string length]);

[attributedString addAttribute:NSParagraphStyleAttributeName value:paragraphStyle range:range];

return attributedString;

}

@end

用起来到底怎么样呢?请看下面的测试效果:

单行 多行

再来看下带有行间距的:

单行 多行

最近发现了一个问题,UILabel的category如果调用- (NSMutableAttributedString *)attributedStringWith:(NSString *)string lineSpace:(CGFloat)lineSpace limitWidth:(CGFloat)limitWidth设置文字的话,当label空间不够末尾需要显示省略号时会不显示省略号,为了修改这个问题,我对该方法做了点补充,如下:

- (NSMutableAttributedString *)attributedStringWith:(NSString *)string lineSpace:(CGFloat)lineSpace limitWidth:(CGFloat)limitWidth {

if (string == nil) {

string = @"";

}

self.width = limitWidth;

self.text = string;

lineSpace = self.textNumberOfLines > 1 ? lineSpace : 0;

NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:string];

NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];

paragraphStyle.lineSpacing = lineSpace; // 调整行间距

paragraphStyle.lineBreakMode = NSLineBreakByTruncatingTail;

NSRange range = NSMakeRange(0, [string length]);

[attributedString addAttribute:NSParagraphStyleAttributeName value:paragraphStyle range:range];

return attributedString;

}

其实只增加了 paragraphStyle.lineBreakMode = NSLineBreakByTruncatingTail;一句代码而已,在之后的文章我会对这个问题做个单独的说明,GitHub上的demo同步更新

GitHub上的demo

上一篇下一篇

猜你喜欢

热点阅读