学习了网上的一些CoreText知识之后,总结了一下学习成果,自定义了一个Label控件。
Label特点:
1、可以设置文本中某些字段为关键字;
2、可以设置文本颜色和其中关键字的颜色;
3、可以设置文本下划线样式和其中关键字下划线样式;
4、可以指定文本字体与大小和其中关键字的字体与大小;
5、可以响应关键字点击;
说明一下其中的关键类的意义:
CHLabel.h 自定义的控件,继承自UILabel;
TestViewController.h 是项目的根视图控制器,其中使用了CHLabel;
下面看代码:
CHLabel 代码实现:
- #import<UIKit/UIKit.h>
- #import<CoreText/CoreText.h>
- typedefenum
- {
- kCHLabelUnderlineStyleNone=0,
- kCHLabelUnderlineStyleSingle,
- kCHLabelUnderlineStyleThick,
- kCHLabelUnderlineStyleDouble
- }CHLabelUnderlineStyle;
- @protocolCHLabelDelegate;
- @interfaceCHLabel:UILabel
- {
- NSString*_textCH;//文本
- UIColor*_textColorCH;//文本颜色
- UIFont*_textFontCH;//文本字体
- CHLabelUnderlineStyle_textUnderlineStyle;//文本下划线
- NSString*_textKeyWordCH;//关键字
- UIColor*_textKeyWordColorCH;//关键字颜色
- UIFont*_keyWordFontCH;//关键字字体
- CHLabelUnderlineStyle_keyWordUnderlineStyle;//关键字下划线
- NSMutableArray*_keyWordsCH;//关键字数组
- NSMutableAttributedString*_attributedString;//属性字符串
- }
- @property(nonatomic,copy)NSString*textCH;
- @property(nonatomic,retain)UIColor*textColorCH;
- @property(nonatomic,copy)NSString*textKeyWordCH;
- @property(nonatomic,retain)UIColor*textKeyWordColorCH;
- @property(nonatomic,retain)UIFont*textFontCH;
- @property(nonatomic,retain)UIFont*keyWordFontCH;
- @property(nonatomic,retain)NSMutableArray*keyWordsCH;
- @property(nonatomic,retain)NSMutableAttributedString*attributedString;
- @property(nonatomic,retain)id<CHLabelDelegate>delegate;
- -(void)setText:(NSString*)textStringandKeyWord:(NSString*)keyWord;
- -(void)setTextColor:(UIColor*)textColorandKeyWordColor:(UIColor*)keyWordColor;
- -(void)setTextFont:(UIFont*)textFontandKeyWordFont:(UIFont*)keyWordFont;
- -(void)setTextUnderlineStyle:(CHLabelUnderlineStyle)textUnderlineStyleandKeyWordUnderlineStyle:(CHLabelUnderlineStyle)keyWordUnderlineStyle;
- @end
- @protocolCHLabelDelegate<NSObject>
- @optional
- -(void)CHLabel:(CHLabel*)chLabeltapOnKeyWord:(NSString*)keyWord;
- @end
- #import"CHLabel.h"
- @implementationCHLabel
- @synthesizetextCH=_textCH;
- @synthesizetextColorCH=_textColorCH;
- @synthesizetextKeyWordCH=_textKeyWordCH;
- @synthesizetextKeyWordColorCH=_textKeyWordColorCH;
- @synthesizetextFontCH=_textFontCH;
- @synthesizekeyWordFontCH=_keyWordFontCH;
- @synthesizekeyWordsCH=_keyWordsCH;
- @synthesizeattributedString=_attributedString;
- @synthesizedelegate;
- voidsafeRelease(idpointer)
- {
- if(!pointer)
- {
- [pointerrelease];
- pointer=nil;
- }
- }
- -(void)dealloc
- {
- safeRelease(_textCH);
- safeRelease(_textColorCH);
- safeRelease(_textKeyWordCH);
- safeRelease(_textKeyWordColorCH);
- safeRelease(_textFontCH);
- safeRelease(_keyWordFontCH);
- safeRelease(_keyWordsCH);
- safeRelease(_attributedString);
- safeRelease(delegate);
- [superdealloc];
- }
- -(void)initializtion
- {
- _textKeyWordCH=nil;
- _textKeyWordColorCH=nil;
- _keyWordsCH=[[NSMutableArrayalloc]init];
- }
- -(id)init
- {
- if(self=[superinit])
- {
- [selfinitializtion];
- }
- returnself;
- }
- -(id)initWithFrame:(CGRect)frame
- {
- if([superinitWithFrame:frame])
- {
- [selfinitializtion];
- }
- returnself;
- }
- -(void)setText:(NSString*)textStringandKeyWord:(NSString*)keyWord
- {
- if(self.text!=textString)
- {
- self.text=textString;
- self.textCH=textString;
- }
- [selffetchKeywordRange:keyWord];
- }
- -(void)setTextColor:(UIColor*)textColorandKeyWordColor:(UIColor*)keyWordColor
- {
- self.textColorCH=textColor;
- self.textKeyWordColorCH=keyWordColor;
- }
- -(void)setTextFont:(UIFont*)textFontandKeyWordFont:(UIFont*)keyWordFont
- {
- self.textFontCH=textFont;
- self.keyWordFontCH=keyWordFont;
- }
- -(void)setTextUnderlineStyle:(CHLabelUnderlineStyle)textUnderlineStyleandKeyWordUnderlineStyle:(CHLabelUnderlineStyle)keyWordUnderlineStyle
- {
- _textUnderlineStyle=textUnderlineStyle;
- _keyWordUnderlineStyle=keyWordUnderlineStyle;
- }
- -(void)fetchKeywordRange:(NSString*)keyWord
- {
- if(nil==keyWord){
- return;
- }
- NSMutableAttributedString*mutableAttributedString=[[NSMutableAttributedStringalloc]initWithString:self.text];
- NSUIntegercount=0,length=[mutableAttributedStringlength];
- NSRangerange=NSMakeRange(0,length);
- count=0,length=[mutableAttributedStringlength];
- range=NSMakeRange(0,length);
- while(range.location!=NSNotFound)
- {
- range=[[mutableAttributedStringstring]rangeOfString:keyWordoptions:0range:range];
- if(range.location!=NSNotFound){
- NSValue*value=[NSValuevalueWithRange:range];
- if(range.length>0){
- [self.keyWordsCHaddObject:value];
- }
- range=NSMakeRange(range.location+range.length,length-(range.location+range.length));
- count++;
- }
- }
- }
- -(int)labelUnderlineType:(CHLabelUnderlineStyle)lType
- {
- intunderLineType;
- switch(lType){
- case0:
- underLineType=kCTUnderlineStyleNone;
- break;
- case1:
- underLineType=kCTUnderlineStyleSingle;
- break;
- case2:
- underLineType=kCTUnderlineStyleThick;
- break;
- case3:
- underLineType=kCTUnderlineStyleDouble;
- break;
- default:
- underLineType=kCTUnderlineStyleNone;
- break;
- }
- returnunderLineType;
- }
- -(NSAttributedString*)richString:(NSString*)textString
- {
- intlength=[textStringlength];
- if(self.attributedString){
- self.attributedString=nil;
- }
- self.attributedString=[[NSMutableAttributedStringalloc]initWithString:textString];
- [self.attributedStringaddAttribute:(NSString*)(kCTForegroundColorAttributeName)
- value:(id)self.textColorCH.CGColor
- range:NSMakeRange(0,length)];
- intnumType=0;
- CFNumberRefcfNum=CFNumberCreate(NULL,kCFNumberIntType,&numType);
- [self.attributedStringaddAttribute:(NSString*)kCTLigatureAttributeName
- value:(id)cfNum
- range:NSMakeRange(0,length)];
- floatfNum=3.0;
- CFNumberRefcfNum2=CFNumberCreate(NULL,kCFNumberFloatType,&fNum);
- [self.attributedStringaddAttribute:(NSString*)(kCTStrokeColorAttributeName)
- value:(id)cfNum2
- range:NSMakeRange(0,length)];
- if(!self.textFontCH){
- self.textFontCH=self.font;
- }
- CTFontRefctFont=CTFontCreateWithName((CFStringRef)self.textFontCH.fontName,self.textFontCH.pointSize,NULL);
- [self.attributedStringaddAttribute:(NSString*)(kCTFontAttributeName)
- value:(id)ctFont
- range:NSMakeRange(0,length)];
- intunderLineType=[selflabelUnderlineType:_textUnderlineStyle];
- CFNumberRefcfUnderLine=CFNumberCreate(NULL,kCTUnderlineStyleThick,&underLineType);
- [self.attributedStringaddAttribute:(NSString*)(kCTUnderlineStyleAttributeName)
- value:(id)cfUnderLine
- range:NSMakeRange(0,length)];
- if(self.textKeyWordColorCH!=nil)
- {
- for(NSValue*valueinself.keyWordsCH)
- {
- NSRangekeyRange=[valuerangeValue];
- [self.attributedStringaddAttribute:(NSString*)(kCTForegroundColorAttributeName)
- value:(id)self.textKeyWordColorCH.CGColor
- range:keyRange];
- if(!self.keyWordFontCH){
- self.keyWordFontCH=self.font;
- }
- CTFontRefctFont=CTFontCreateWithName((CFStringRef)self.keyWordFontCH.fontName,self.keyWordFontCH.pointSize,NULL);
- [self.attributedStringaddAttribute:(NSString*)(kCTFontAttributeName)
- value:(id)ctFont
- range:keyRange];
- intunderLineType=[selflabelUnderlineType:_keyWordUnderlineStyle];
- CFNumberRefcfUnderLine=CFNumberCreate(NULL,kCTUnderlineStyleThick,&underLineType);
- [self.attributedStringaddAttribute:(NSString*)(kCTUnderlineStyleAttributeName)
- value:(id)cfUnderLine
- range:keyRange];
- [self.attributedStringaddAttribute:@"option"value:[[self.attributedStringstring]substringWithRange:keyRange]range:keyRange];//弹出alert时候需要
- }
- }
- return[[self.attributedStringcopy]autorelease];
- }
- -(void)drawRect:(CGRect)rect
- {
- CGContextRefcontext=UIGraphicsGetCurrentContext();
- CGContextSaveGState(context);
- CGContextConcatCTM(context,CGAffineTransformScale(CGAffineTransformMakeTranslation(0,rect.size.height+6.5),1.f,-1.f));
- CGContextSetTextPosition(context,0.0,0.0);
- CTFramesetterRefframesetter=CTFramesetterCreateWithAttributedString((CFAttributedStringRef)[selfrichString:self.text]);
- //NSLog(@"AttributedString:%@",[selfrichString:self.textfont:self.font]);
- CGMutablePathRefleftColumnPath=CGPathCreateMutable();
- CGPathAddRect(leftColumnPath,NULL,rect);
- CTFrameRefleftFrame=CTFramesetterCreateFrame(framesetter,CFRangeMake(0,0),leftColumnPath,NULL);
- CTFrameDraw(leftFrame,context);
- CGContextRestoreGState(context);
- CGPathRelease(leftColumnPath);
- CFRelease(framesetter);
- }
- -(void)touchesBegan:(NSSet*)toucheswithEvent:(UIEvent*)event{
- [supertouchesEnded:toucheswithEvent:event];
- CGPointtapLocation=[[touchesanyObject]locationInView:self];
- inttotal_height=[selfgetAttributedStringHeightWithString:self.attributedStringWidthValue:self.frame.size.width];//width为自身宽度
- //判断点击是否超出范围
- if(tapLocation.y>=total_height){
- return;
- }
- /**1.SetupCTFramesetter**/
- CTFramesetterRefframesetter=CTFramesetterCreateWithAttributedString((CFAttributedStringRef)self.attributedString);
- /**2.CreateCTFrame**/
- CGMutablePathRefpath=CGPathCreateMutable();
- CGPathAddRect(path,NULL,CGRectMake(0,0,self.frame.size.width,1000));//height越大越好,
- CTFrameReftextFrameForKey=CTFramesetterCreateFrame(framesetter,CFRangeMake(0,0),path,NULL);
- //[selfdrawFrame:textFrameForKeyinContext:nilforString:nil];
- CFRelease(path);
- CFRelease(framesetter);
- //CTFrameGetLineOrigins
- NSArray*linesArray=(NSArray*)CTFrameGetLines(textFrameForKey);
- CGPointorigins[[linesArraycount]];
- CTFrameGetLineOrigins(textFrameForKey,CFRangeMake(0,0),origins);
- CFArrayReflines=CTFrameGetLines(textFrameForKey);
- CGFloatascent;
- CGFloatdescent;
- CGFloatleading;
- CTLineRefline=(CTLineRef)[linesArrayobjectAtIndex:0];
- CTLineGetTypographicBounds(line,&ascent,&descent,&leading);
- //CFIndexlinesCount=CFArrayGetCount(lines);
- intline_y=1000-(int)origins[0].y;//第一行line的原点y坐标
- intline_height=line_y+(int)descent+1;//每行的高度
- intcurrent_line=tapLocation.y/line_height;
- CFIndexcurentIndex=CTLineGetStringIndexForPosition((CTLineRef)CFArrayGetValueAtIndex(lines,current_line),tapLocation);
- //判断超出范围
- if(curentIndex>[self.attributedStringlength]){
- return;
- }
- NSRangecurrentRange=NSMakeRange(0,[self.attributedStringlength]);
- //curentIndex
- NSDictionary*dic=[self.attributedStringattributesAtIndex:curentIndex-1effectiveRange:¤tRange];
- idoption=[dicvalueForKey:@"option"];
- if(option){
- if([delegaterespondsToSelector:@selector(CHLabel:tapOnKeyWord:)])
- {
- [delegateCHLabel:selftapOnKeyWord:(NSString*)[dicvalueForKey:@"option"]];
- }
- }
- }
- //获取coretext高度
- -(int)getAttributedStringHeightWithString:(NSAttributedString*)stringWidthValue:(int)width
- {
- inttotal_height=0;
- //string为要计算高度的NSAttributedString
- CTFramesetterRefframesetter=CTFramesetterCreateWithAttributedString((CFAttributedStringRef)string);
- CGRectdrawingRect=CGRectMake(0,0,width,1000);//这里的高要设置足够大
- CGMutablePathRefpath=CGPathCreateMutable();
- CGPathAddRect(path,NULL,drawingRect);
- CTFrameReftextFrame=CTFramesetterCreateFrame(framesetter,CFRangeMake(0,0),path,NULL);
- CGPathRelease(path);
- CFRelease(framesetter);
- NSArray*linesArray=(NSArray*)CTFrameGetLines(textFrame);
- CGPointorigins[[linesArraycount]];
- CTFrameGetLineOrigins(textFrame,CFRangeMake(0,0),origins);
- intline_y=(int)origins[[linesArraycount]-1].y;//最后一行line的原点y坐标
- CGFloatascent;
- CGFloatdescent;
- CGFloatleading;
- CTLineRefline=(CTLineRef)[linesArrayobjectAtIndex:[linesArraycount]-1];
- CTLineGetTypographicBounds(line,&ascent,&descent,&leading);
- total_height=1000-line_y+(int)descent+1;//+1为了纠正descent转换成int小数点后舍去的值
- CFRelease(textFrame);
- returntotal_height;
- }
- @end
- TestViewController.h代码实现:
- @interfaceTestViewController:UIViewController<CHLabelDelegate>
- {
- IBOutletUITextField*textString;
- IBOutletUITextField*keyString;
- }
- -(IBAction)showText:(id)sender;
- @end
- #import"TestViewController.h"
- @interfaceTestViewController()
- @end
- @implementationTestViewController
- -(id)initWithNibName:(NSString*)nibNameOrNilbundle:(NSBundle*)nibBundleOrNil
- {
- self=[superinitWithNibName:nibNameOrNilbundle:nibBundleOrNil];
- if(self){
- //Custominitialization
- }
- returnself;
- }
- -(IBAction)showText:(id)sender
- {
- [textStringresignFirstResponder];
- [keyStringresignFirstResponder];
- CHLabel*label=[[CHLabelalloc]initWithFrame:CGRectMake(10,260,300,200)];
- [labelsetUserInteractionEnabled:YES];
- [labelsetText:textString.textandKeyWord:keyString.text];
- [labelsetTextColor:[UIColorredColor]andKeyWordColor:[UIColorblueColor]];
- [labelsetTextUnderlineStyle:kCHLabelUnderlineStyleSingleandKeyWordUnderlineStyle:kCHLabelUnderlineStyleDouble];
- [labelsetTextFont:[UIFontsystemFontOfSize:20]andKeyWordFont:[UIFontboldSystemFontOfSize:30]];
- label.backgroundColor=[UIColorlightGrayColor];
- [labelsetNumberOfLines:0];
- label.delegate=self;
- NSArray*fontArray=[UIFontfamilyNames];
- NSString*fontName;
- if([fontArraycount]){
- fontName=[fontArrayobjectAtIndex:0];
- }
- [labelsetFont:[UIFontfontWithName:fontNamesize:20]];
- [self.viewaddSubview:label];
- //[labelsetNeedsDisplay];
- [labelrelease];
- }
- -(void)viewDidLoad
- {
- [superviewDidLoad];
- }
- -(void)didReceiveMemoryWarning
- {
- [superdidReceiveMemoryWarning];
- }
- #pragmamarkCHLabelDelegate
- -(void)CHLabel:(CHLabel*)chLabeltapOnKeyWord:(NSString*)keyWord
- {
- UIAlertView*alert=[[UIAlertViewalloc]initWithTitle:@"notice"
- message:[NSStringstringWithFormat:@"TaponkeyWord:%@",keyWord]
- delegate:nil
- cancelButtonTitle:@"OK"
- otherButtonTitles:nil];
- [alertshow];
- [alertrelease];
}
完整的项目链接:http://pan.baidu.com/share/link?shareid=362100&uk=3674861929
转载请保留,原文链接:http://blog.csdn.net/zfpp25_/article/details/8639215
若发现有不合适或错误之处,还请批评指正,不胜感激。