UILabel - 自定義行間距,字間距及段間距[並動態調節高](轉)


1.如若各項參數無需動態調節則可無視characterSpacing_linesSpacing_.

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 = &paragraphSpacing;

//創建設置數組
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];


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM