[這是第四篇]
導(dǎo)語:在iOS中方篮,有時(shí)候顯示文本,需要設(shè)置文本的行間距励负、指定顯示行數(shù)藕溅、如果文本內(nèi)容超出顯示行數(shù),省略結(jié)尾部分的內(nèi)容以……方式省略继榆。這些都可以使用UILabel來是實(shí)現(xiàn)巾表,前提是你擴(kuò)展了UILabel這方面的特性汁掠。
——2017年4月14日
新增的特性
之前已經(jīng)寫過這部分內(nèi)容,但是代碼不簡潔集币,使用不太方便考阱,現(xiàn)在重新表述一下,思路是一樣的
1鞠苟、可以設(shè)置文本的顯示行數(shù)乞榨。文本內(nèi)容超出顯示行數(shù),結(jié)尾部分的內(nèi)容以……方式省略偶妖,文本內(nèi)容不超出顯示行數(shù)姜凄,默認(rèn)顯示全部文本。
2趾访、可以設(shè)置行間距态秧。
一 、代碼實(shí)現(xiàn)
1-1扼鞋、新增NSString 的Size分類定義申鱼,用來計(jì)算文本占據(jù)的size#####
// NSString+Size.h
@interface NSString (Size)
/**
根據(jù)字體、行數(shù)云头、行間距和constrainedWidth計(jì)算文本占據(jù)的size
@param font 字體
@param numberOfLines 顯示文本行數(shù)捐友,值為0不限制行數(shù)
@param lineSpacing 行間距
@param constrainedWidth 文本受限的寬度
@param isLimitedToLines 記錄文本是否被numberOfLines限制
@return 返回文本占據(jù)的size
*/
- (CGSize)textSizeWithFont:(UIFont*)font
numberOfLines:(NSInteger)numberOfLines
lineSpacing:(CGFloat)lineSpacing
constrainedWidth:(CGFloat)constrainedWidth
isLimitedToLines:(BOOL *)isLimitedToLines;
@end
- 將文本size的計(jì)算放到NSString的分類中,是合情合理的溃槐,之前放到UILabel的分類中匣砖,這點(diǎn)不太好。
- isLimitedToLines是用來記錄文本是否被numberOfLines限制昏滴,在業(yè)務(wù)中是為了控制文本的展開和收起(后面有Demo)猴鲫。
1-2、NSString+Size的重要實(shí)現(xiàn)
- (CGSize)textSizeWithFont:(UIFont*)font
numberOfLines:(NSInteger)numberOfLines
lineSpacing:(CGFloat)lineSpacing
constrainedWidth:(CGFloat)constrainedWidth
isLimitedToLines:(BOOL *)isLimitedToLines{
if (self.length == 0) {
return CGSizeZero;
}
CGFloat oneLineHeight = font.lineHeight;
CGSize textSize = [self boundingRectWithSize:CGSizeMake(constrainedWidth, MAXFLOAT) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName:font} context:nil].size;
CGFloat rows = textSize.height / oneLineHeight;
CGFloat realHeight = oneLineHeight;
// 0 不限制行數(shù)
if (numberOfLines == 0) {
if (rows >= 1) {
realHeight = (rows * oneLineHeight) + (rows - 1) * lineSpacing;
}
}else{
if (rows > numberOfLines) {
rows = numberOfLines;
if (isLimitedToLines) {
*isLimitedToLines = YES; //被限制
}
}
realHeight = (rows * oneLineHeight) + (rows - 1) * lineSpacing;
}
return CGSizeMake(constrainedWidth, realHeight);
}
2-1谣殊、新增UILabel 的FitLines分類拂共,讓文本適應(yīng)于指定的行數(shù)
// UILabel+FitLines.h
@interface UILabel (FitLines)
/**
最大顯示寬度
*/
@property (nonatomic,assign)CGFloat qsConstrainedWidth;
/**
行間距
*/
@property (nonatomic,assign)CGFloat qsLineSpacing;
/**
文本適應(yīng)于指定的行數(shù)
@return 文本是否被numberOfLines限制
*/
- (BOOL)qs_adjustTextToFitLines:(NSInteger)numberOfLines;
@end
- 在初始化UILabel的時(shí)候,設(shè)置qsConstrainedWidth和qsLineSpacing姻几,然后需要展示UILabel的內(nèi)容時(shí)候宜狐,調(diào)用qs_adjustTextToFitLines就可以了,相應(yīng)設(shè)置好frame就好了蛇捌。
2-2抚恒、UILabel+FitLines的重要實(shí)現(xiàn)
- (BOOL)qs_adjustTextToFitLines:(NSInteger)numberOfLines{
if (!self.text || self.text.length == 0) {
return NO;
}
self.numberOfLines = numberOfLines;
BOOL isLimitedToLines = NO;
CGSize textSize = [self.text textSizeWithFont:self.font numberOfLines:self.numberOfLines lineSpacing:self.qsLineSpacing constrainedWidth:self.qsConstrainedWidth isLimitedToLines:&isLimitedToLines];
//單行的情況
if (fabs(textSize.height - self.font.lineHeight) < 0.00001f) {
self.qsLineSpacing = 0.0f;
}
//設(shè)置文字的屬性
NSMutableAttributedString * attributedString = [[NSMutableAttributedString alloc] initWithString:self.text];
NSMutableParagraphStyle * paragraphStyle = [[NSMutableParagraphStyle alloc] init];
[paragraphStyle setLineSpacing:self.qsLineSpacing];
paragraphStyle.lineBreakMode = NSLineBreakByTruncatingTail;//結(jié)尾部分的內(nèi)容以……方式省略
[attributedString addAttribute:NSParagraphStyleAttributeName value:paragraphStyle range:NSMakeRange(0, [self.text length])];
[attributedString addAttribute:NSForegroundColorAttributeName value:self.textColor range:NSMakeRange(0, [self.text length])];
[attributedString addAttribute:NSFontAttributeName value:self.font range:NSMakeRange(0, [self.text length])];
[self setAttributedText:attributedString];
self.bounds = CGRectMake(0, 0, textSize.width, textSize.height);
return isLimitedToLines;
}
三、使用(初始化和顯示文本)
- (UILabel *)contentLabel{
if (!_contentLabel) {
_contentLabel = [[UILabel alloc] init];
_contentLabel.backgroundColor = [UIColor clearColor];
_contentLabel.font = [UIFont systemFontOfSize:QSTextFontSize];
_contentLabel.textColor = [UIColor blackColor];
_contentLabel.qsConstrainedWidth = SCREEN_WIDTH - 30;
_contentLabel.qsLineSpacing = QSTextLineSpacing;
}
return _contentLabel;
}
- (void)layoutSubviewsWithModel:(QSShowTextCellModel *)model{
//...
_contentLabel.text = model.content;
BOOL isLimitedToLines = [_contentLabel qs_adjustTextToFitLines:model.contentLines];
_contentLabel.frame = CGRectMake(15, CGRectGetMaxY(self.titleLabel.frame) + 10,
CGRectGetWidth( _contentLabel.bounds),CGRectGetHeight(_contentLabel.bounds));
// ...
}
- 其他代碼見Demo
四络拌、UILabel擴(kuò)展特性的使用
- 這個(gè)Demo是使用UITableView組織文本的顯示柑爸。每一個(gè)cell可以顯示title和content,cell中先指定content文本顯示3行盒音,行間距是5.0f
- 如果content文本用3行不能全部顯示表鳍,文本下面出現(xiàn)“顯示文本”按鈕,點(diǎn)擊“顯示全文”按鈕祥诽,可以展開全部文本譬圣,此時(shí)按鈕變成“收起全文”;點(diǎn)擊按鈕可以收起全文雄坪,依舊顯示3行厘熟,按鈕恢復(fù)成“顯示全文”。
- 如果content文本用3行可以全部顯示维哈,不會(huì)出現(xiàn)按鈕绳姨。
- content顯示的文本可以設(shè)置行數(shù)值,行間距值阔挠,收起全文和展開全文都是利用UILabel的擴(kuò)展特性來實(shí)現(xiàn)的飘庄。
- demo中使用cellModel保存cell中content顯示的行數(shù)-- contentLines,通過contentlines來預(yù)先計(jì)算cell的高度购撼。具體參見Demo源碼跪削。
** 效果圖如下**
源碼直通車:QSUseLabelDemo
如果可以解決您的問題,請(qǐng)star一下哈??