MartinCustomLabel.h
#import<Foundation/Foundation.h> #import<UIKit/UIKit.h> @interface MartinCustomLabel : UILabel { @private CGFloat characterSpacing_; //字间距 long linesSpacing_; //行间距 } @property(nonatomic,assign) CGFloat characterSpacing; @property(nonatomic,assign) long linesSpacing; /* *绘制前获取label高度 */ - (int)getAttributedStringHeightWidthValue:(int)width; @end
2.因为我无需动态调节行,字,段.所以我在代码中是写的常量.可按自身需求修改.
MartinCustomLabel.m
#import "MartinCustomLabel.h" #import<CoreText/CoreText.h> @interface MartinCustomLabel() { @private NSMutableAttributedString *attributedString; } - (void) initAttributedString; @end @implementation MartinCustomLabel @synthesize characterSpacing = characterSpacing_; @synthesize linesSpacing = linesSpacing_; -(id) initWithFrame:(CGRect)frame { //初始化字间距、行间距 if(self =[super initWithFrame:frame]) { self.characterSpacing = 1.5f; self.linesSpacing = 4.0f; } return self; } //外部调用设置字间距 -(void)setCharacterSpacing:(CGFloat)characterSpacing { characterSpacing_ = characterSpacing; [self setNeedsDisplay]; } //外部调用设置行间距 -(void)setLinesSpacing:(long)linesSpacing { linesSpacing_ = linesSpacing; [self setNeedsDisplay]; } /* *初始化AttributedString并进行相应设置 */ - (void) initAttributedString { if(attributedString==nil){ //去掉空行 NSString *labelString = self.text; NSString *myString = [labelString stringByReplacingOccurrencesOfString:@"\r\n" withString:@"\n"]; //创建AttributeString attributedString =[[NSMutableAttributedString alloc]initWithString:myString]; //设置字体及大小 CTFontRef helveticaBold = CTFontCreateWithName((CFStringRef)self.font.fontName,self.font.pointSize,NULL); [attributedString addAttribute:(id)kCTFontAttributeName value:(id)helveticaBold range:NSMakeRange(0,[attributedString length])]; //设置字间距 long number = 1.5f; CFNumberRef num = CFNumberCreate(kCFAllocatorDefault,kCFNumberSInt8Type,&number); [attributedString addAttribute:(id)kCTKernAttributeName value:(id)num range:NSMakeRange(0,[attributedString length])]; CFRelease(num); /* if(self.characterSpacing) { long number = self.characterSpacing; CFNumberRef num = CFNumberCreate(kCFAllocatorDefault,kCFNumberSInt8Type,&number); [attributedString addAttribute:(id)kCTKernAttributeName value:(id)num range:NSMakeRange(0,[attributedString length])]; CFRelease(num); } */ //设置字体颜色 [attributedString addAttribute:(id)kCTForegroundColorAttributeName value:(id)(self.textColor.CGColor) range:NSMakeRange(0,[attributedString length])]; //创建文本对齐方式 CTTextAlignment alignment = kCTLeftTextAlignment; if(self.textAlignment == UITextAlignmentCenter) { alignment = kCTCenterTextAlignment; } if(self.textAlignment == UITextAlignmentRight) { alignment = kCTRightTextAlignment; } CTParagraphStyleSetting alignmentStyle; alignmentStyle.spec = kCTParagraphStyleSpecifierAlignment; alignmentStyle.valueSize = sizeof(alignment); alignmentStyle.value = &alignment; //设置文本行间距 /* CGFloat lineSpace = self.linesSpacing; */ CGFloat lineSpace = 4.0f; CTParagraphStyleSetting lineSpaceStyle; lineSpaceStyle.spec = kCTParagraphStyleSpecifierLineSpacingAdjustment; lineSpaceStyle.valueSize = sizeof(lineSpace); lineSpaceStyle.value =&lineSpace; //设置文本段间距 CGFloat paragraphSpacing = 15.0; CTParagraphStyleSetting paragraphSpaceStyle; paragraphSpaceStyle.spec = kCTParagraphStyleSpecifierParagraphSpacing; paragraphSpaceStyle.valueSize = sizeof(CGFloat); paragraphSpaceStyle.value = ¶graphSpacing; //创建设置数组 CTParagraphStyleSetting settings[ ] ={alignmentStyle,lineSpaceStyle,paragraphSpaceStyle}; CTParagraphStyleRef style = CTParagraphStyleCreate(settings ,3); //给文本添加设置 [attributedString addAttribute:(id)kCTParagraphStyleAttributeName value:(id)style range:NSMakeRange(0 , [attributedString length])]; CFRelease(helveticaBold); } } /* *覆写setText方法 */ - (void) setText:(NSString *)text { [super setText:text]; [self initAttributedString]; } /* *开始绘制 */ -(void) drawTextInRect:(CGRect)requestedRect { [self initAttributedString]; //排版 CTFramesetterRef framesetter = CTFramesetterCreateWithAttributedString((CFAttributedStringRef)attributedString); CGMutablePathRef leftColumnPath = CGPathCreateMutable(); CGPathAddRect(leftColumnPath, NULL ,CGRectMake(0 , 0 ,self.bounds.size.width , self.bounds.size.height)); CTFrameRef leftFrame = CTFramesetterCreateFrame(framesetter,CFRangeMake(0, 0), leftColumnPath , NULL); //翻转坐标系统(文本原来是倒的要翻转下) CGContextRef context = UIGraphicsGetCurrentContext(); CGContextSetTextMatrix(context , CGAffineTransformIdentity); CGContextTranslateCTM(context , 0 ,self.bounds.size.height); CGContextScaleCTM(context, 1.0 ,-1.0); //画出文本 CTFrameDraw(leftFrame,context); //释放 CGPathRelease(leftColumnPath); CFRelease(framesetter); UIGraphicsPushContext(context); } /* *绘制前获取label高度 */ - (int)getAttributedStringHeightWidthValue:(int)width { [self initAttributedString]; int total_height = 0; CTFramesetterRef framesetter = CTFramesetterCreateWithAttributedString((CFAttributedStringRef)attributedString); //string 为要计算高度的NSAttributedString CGRect drawingRect = CGRectMake(0, 0, width, 100000); //这里的高要设置足够大 CGMutablePathRef path = CGPathCreateMutable(); CGPathAddRect(path, NULL, drawingRect); CTFrameRef textFrame = CTFramesetterCreateFrame(framesetter,CFRangeMake(0,0), path, NULL); CGPathRelease(path); CFRelease(framesetter); NSArray *linesArray = (NSArray *) CTFrameGetLines(textFrame); CGPoint origins[[linesArray count]]; CTFrameGetLineOrigins(textFrame, CFRangeMake(0, 0), origins); int line_y = (int) origins[[linesArray count] -1].y; //最后一行line的原点y坐标 CGFloat ascent; CGFloat descent; CGFloat leading; CTLineRef line = (CTLineRef) [linesArray objectAtIndex:[linesArray count]-1]; CTLineGetTypographicBounds(line, &ascent, &descent, &leading); total_height = 100000 - line_y + (int) descent +1;//+1为了纠正descent转换成int小数点后舍去的值 CFRelease(textFrame); return total_height; } @end
3.创建调用步骤:
MartinCustomLabel *readNewsLable =[[MartinCustomLabel alloc] initWithFrame:CGRectZero]; readNewsLable.textColor = textCor; readNewsLable.lineBreakMode = UILineBreakModeWordWrap; readNewsLable.backgroundColor = [UIColor clearColor]; readNewsLable.font = TEXT_FONT_NAME([AccessData getNewsConnectFont]); [readNewsLable setText:text]; /*设置label的frame值*/ [readNewsLable setFrame:CGRectMake(10, aboveY, WINDOW_W-20, [readNewsLable getAttributedStringHeightWidthValue:WINDOW_W-20])]; readNewsLable.numberOfLines = 0; [readNewsLable setTag:TEXT_LABEL_TAG+tag]; [self addSubview:readNewsLable];