做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同步更新
网友评论