CoreText入门

学习了网上的一些CoreText知识之后,总结了一下学习成果,自定义了一个Label控件。

Label特点:

1、可以设置文本中某些字段为关键字;

2、可以设置文本颜色和其中关键字的颜色;

3、可以设置文本下划线样式和其中关键字下划线样式;

4、可以指定文本字体与大小和其中关键字的字体与大小;

5、可以响应关键字点击;


说明一下其中的关键类的意义:

CHLabel.h 自定义的控件,继承自UILabel;

TestViewController.h 是项目的根视图控制器,其中使用了CHLabel;


下面看代码:

CHLabel 代码实现:

  1. #import<UIKit/UIKit.h>
  2. #import<CoreText/CoreText.h>
  3. typedefenum
  4. {
  5. kCHLabelUnderlineStyleNone=0,
  6. kCHLabelUnderlineStyleSingle,
  7. kCHLabelUnderlineStyleThick,
  8. kCHLabelUnderlineStyleDouble
  9. }CHLabelUnderlineStyle;
  10. @protocolCHLabelDelegate;
  11. @interfaceCHLabel:UILabel
  12. {
  13. NSString*_textCH;//文本
  14. UIColor*_textColorCH;//文本颜色
  15. UIFont*_textFontCH;//文本字体
  16. CHLabelUnderlineStyle_textUnderlineStyle;//文本下划线
  17. NSString*_textKeyWordCH;//关键字
  18. UIColor*_textKeyWordColorCH;//关键字颜色
  19. UIFont*_keyWordFontCH;//关键字字体
  20. CHLabelUnderlineStyle_keyWordUnderlineStyle;//关键字下划线
  21. NSMutableArray*_keyWordsCH;//关键字数组
  22. NSMutableAttributedString*_attributedString;//属性字符串
  23. }
  24. @property(nonatomic,copy)NSString*textCH;
  25. @property(nonatomic,retain)UIColor*textColorCH;
  26. @property(nonatomic,copy)NSString*textKeyWordCH;
  27. @property(nonatomic,retain)UIColor*textKeyWordColorCH;
  28. @property(nonatomic,retain)UIFont*textFontCH;
  29. @property(nonatomic,retain)UIFont*keyWordFontCH;
  30. @property(nonatomic,retain)NSMutableArray*keyWordsCH;
  31. @property(nonatomic,retain)NSMutableAttributedString*attributedString;
  32. @property(nonatomic,retain)id<CHLabelDelegate>delegate;
  33. -(void)setText:(NSString*)textStringandKeyWord:(NSString*)keyWord;
  34. -(void)setTextColor:(UIColor*)textColorandKeyWordColor:(UIColor*)keyWordColor;
  35. -(void)setTextFont:(UIFont*)textFontandKeyWordFont:(UIFont*)keyWordFont;
  36. -(void)setTextUnderlineStyle:(CHLabelUnderlineStyle)textUnderlineStyleandKeyWordUnderlineStyle:(CHLabelUnderlineStyle)keyWordUnderlineStyle;
  37. @end
  38. @protocolCHLabelDelegate<NSObject>
  39. @optional
  40. -(void)CHLabel:(CHLabel*)chLabeltapOnKeyWord:(NSString*)keyWord;
  41. @end
  42. #import"CHLabel.h"
  43. @implementationCHLabel
  44. @synthesizetextCH=_textCH;
  45. @synthesizetextColorCH=_textColorCH;
  46. @synthesizetextKeyWordCH=_textKeyWordCH;
  47. @synthesizetextKeyWordColorCH=_textKeyWordColorCH;
  48. @synthesizetextFontCH=_textFontCH;
  49. @synthesizekeyWordFontCH=_keyWordFontCH;
  50. @synthesizekeyWordsCH=_keyWordsCH;
  51. @synthesizeattributedString=_attributedString;
  52. @synthesizedelegate;
  53. voidsafeRelease(idpointer)
  54. {
  55. if(!pointer)
  56. {
  57. [pointerrelease];
  58. pointer=nil;
  59. }
  60. }
  61. -(void)dealloc
  62. {
  63. safeRelease(_textCH);
  64. safeRelease(_textColorCH);
  65. safeRelease(_textKeyWordCH);
  66. safeRelease(_textKeyWordColorCH);
  67. safeRelease(_textFontCH);
  68. safeRelease(_keyWordFontCH);
  69. safeRelease(_keyWordsCH);
  70. safeRelease(_attributedString);
  71. safeRelease(delegate);
  72. [superdealloc];
  73. }
  74. -(void)initializtion
  75. {
  76. _textKeyWordCH=nil;
  77. _textKeyWordColorCH=nil;
  78. _keyWordsCH=[[NSMutableArrayalloc]init];
  79. }
  80. -(id)init
  81. {
  82. if(self=[superinit])
  83. {
  84. [selfinitializtion];
  85. }
  86. returnself;
  87. }
  88. -(id)initWithFrame:(CGRect)frame
  89. {
  90. if([superinitWithFrame:frame])
  91. {
  92. [selfinitializtion];
  93. }
  94. returnself;
  95. }
  96. -(void)setText:(NSString*)textStringandKeyWord:(NSString*)keyWord
  97. {
  98. if(self.text!=textString)
  99. {
  100. self.text=textString;
  101. self.textCH=textString;
  102. }
  103. [selffetchKeywordRange:keyWord];
  104. }
  105. -(void)setTextColor:(UIColor*)textColorandKeyWordColor:(UIColor*)keyWordColor
  106. {
  107. self.textColorCH=textColor;
  108. self.textKeyWordColorCH=keyWordColor;
  109. }
  110. -(void)setTextFont:(UIFont*)textFontandKeyWordFont:(UIFont*)keyWordFont
  111. {
  112. self.textFontCH=textFont;
  113. self.keyWordFontCH=keyWordFont;
  114. }
  115. -(void)setTextUnderlineStyle:(CHLabelUnderlineStyle)textUnderlineStyleandKeyWordUnderlineStyle:(CHLabelUnderlineStyle)keyWordUnderlineStyle
  116. {
  117. _textUnderlineStyle=textUnderlineStyle;
  118. _keyWordUnderlineStyle=keyWordUnderlineStyle;
  119. }
  120. -(void)fetchKeywordRange:(NSString*)keyWord
  121. {
  122. if(nil==keyWord){
  123. return;
  124. }
  125. NSMutableAttributedString*mutableAttributedString=[[NSMutableAttributedStringalloc]initWithString:self.text];
  126. NSUIntegercount=0,length=[mutableAttributedStringlength];
  127. NSRangerange=NSMakeRange(0,length);
  128. count=0,length=[mutableAttributedStringlength];
  129. range=NSMakeRange(0,length);
  130. while(range.location!=NSNotFound)
  131. {
  132. range=[[mutableAttributedStringstring]rangeOfString:keyWordoptions:0range:range];
  133. if(range.location!=NSNotFound){
  134. NSValue*value=[NSValuevalueWithRange:range];
  135. if(range.length>0){
  136. [self.keyWordsCHaddObject:value];
  137. }
  138. range=NSMakeRange(range.location+range.length,length-(range.location+range.length));
  139. count++;
  140. }
  141. }
  142. }
  143. -(int)labelUnderlineType:(CHLabelUnderlineStyle)lType
  144. {
  145. intunderLineType;
  146. switch(lType){
  147. case0:
  148. underLineType=kCTUnderlineStyleNone;
  149. break;
  150. case1:
  151. underLineType=kCTUnderlineStyleSingle;
  152. break;
  153. case2:
  154. underLineType=kCTUnderlineStyleThick;
  155. break;
  156. case3:
  157. underLineType=kCTUnderlineStyleDouble;
  158. break;
  159. default:
  160. underLineType=kCTUnderlineStyleNone;
  161. break;
  162. }
  163. returnunderLineType;
  164. }
  165. -(NSAttributedString*)richString:(NSString*)textString
  166. {
  167. intlength=[textStringlength];
  168. if(self.attributedString){
  169. self.attributedString=nil;
  170. }
  171. self.attributedString=[[NSMutableAttributedStringalloc]initWithString:textString];
  172. [self.attributedStringaddAttribute:(NSString*)(kCTForegroundColorAttributeName)
  173. value:(id)self.textColorCH.CGColor
  174. range:NSMakeRange(0,length)];
  175. intnumType=0;
  176. CFNumberRefcfNum=CFNumberCreate(NULL,kCFNumberIntType,&numType);
  177. [self.attributedStringaddAttribute:(NSString*)kCTLigatureAttributeName
  178. value:(id)cfNum
  179. range:NSMakeRange(0,length)];
  180. floatfNum=3.0;
  181. CFNumberRefcfNum2=CFNumberCreate(NULL,kCFNumberFloatType,&fNum);
  182. [self.attributedStringaddAttribute:(NSString*)(kCTStrokeColorAttributeName)
  183. value:(id)cfNum2
  184. range:NSMakeRange(0,length)];
  185. if(!self.textFontCH){
  186. self.textFontCH=self.font;
  187. }
  188. CTFontRefctFont=CTFontCreateWithName((CFStringRef)self.textFontCH.fontName,self.textFontCH.pointSize,NULL);
  189. [self.attributedStringaddAttribute:(NSString*)(kCTFontAttributeName)
  190. value:(id)ctFont
  191. range:NSMakeRange(0,length)];
  192. intunderLineType=[selflabelUnderlineType:_textUnderlineStyle];
  193. CFNumberRefcfUnderLine=CFNumberCreate(NULL,kCTUnderlineStyleThick,&underLineType);
  194. [self.attributedStringaddAttribute:(NSString*)(kCTUnderlineStyleAttributeName)
  195. value:(id)cfUnderLine
  196. range:NSMakeRange(0,length)];
  197. if(self.textKeyWordColorCH!=nil)
  198. {
  199. for(NSValue*valueinself.keyWordsCH)
  200. {
  201. NSRangekeyRange=[valuerangeValue];
  202. [self.attributedStringaddAttribute:(NSString*)(kCTForegroundColorAttributeName)
  203. value:(id)self.textKeyWordColorCH.CGColor
  204. range:keyRange];
  205. if(!self.keyWordFontCH){
  206. self.keyWordFontCH=self.font;
  207. }
  208. CTFontRefctFont=CTFontCreateWithName((CFStringRef)self.keyWordFontCH.fontName,self.keyWordFontCH.pointSize,NULL);
  209. [self.attributedStringaddAttribute:(NSString*)(kCTFontAttributeName)
  210. value:(id)ctFont
  211. range:keyRange];
  212. intunderLineType=[selflabelUnderlineType:_keyWordUnderlineStyle];
  213. CFNumberRefcfUnderLine=CFNumberCreate(NULL,kCTUnderlineStyleThick,&underLineType);
  214. [self.attributedStringaddAttribute:(NSString*)(kCTUnderlineStyleAttributeName)
  215. value:(id)cfUnderLine
  216. range:keyRange];
  217. [self.attributedStringaddAttribute:@"option"value:[[self.attributedStringstring]substringWithRange:keyRange]range:keyRange];//弹出alert时候需要
  218. }
  219. }
  220. return[[self.attributedStringcopy]autorelease];
  221. }
  222. -(void)drawRect:(CGRect)rect
  223. {
  224. CGContextRefcontext=UIGraphicsGetCurrentContext();
  225. CGContextSaveGState(context);
  226. CGContextConcatCTM(context,CGAffineTransformScale(CGAffineTransformMakeTranslation(0,rect.size.height+6.5),1.f,-1.f));
  227. CGContextSetTextPosition(context,0.0,0.0);
  228. CTFramesetterRefframesetter=CTFramesetterCreateWithAttributedString((CFAttributedStringRef)[selfrichString:self.text]);
  229. //NSLog(@"AttributedString:%@",[selfrichString:self.textfont:self.font]);
  230. CGMutablePathRefleftColumnPath=CGPathCreateMutable();
  231. CGPathAddRect(leftColumnPath,NULL,rect);
  232. CTFrameRefleftFrame=CTFramesetterCreateFrame(framesetter,CFRangeMake(0,0),leftColumnPath,NULL);
  233. CTFrameDraw(leftFrame,context);
  234. CGContextRestoreGState(context);
  235. CGPathRelease(leftColumnPath);
  236. CFRelease(framesetter);
  237. }
  238. -(void)touchesBegan:(NSSet*)toucheswithEvent:(UIEvent*)event{
  239. [supertouchesEnded:toucheswithEvent:event];
  240. CGPointtapLocation=[[touchesanyObject]locationInView:self];
  241. inttotal_height=[selfgetAttributedStringHeightWithString:self.attributedStringWidthValue:self.frame.size.width];//width为自身宽度
  242. //判断点击是否超出范围
  243. if(tapLocation.y>=total_height){
  244. return;
  245. }
  246. /**1.SetupCTFramesetter**/
  247. CTFramesetterRefframesetter=CTFramesetterCreateWithAttributedString((CFAttributedStringRef)self.attributedString);
  248. /**2.CreateCTFrame**/
  249. CGMutablePathRefpath=CGPathCreateMutable();
  250. CGPathAddRect(path,NULL,CGRectMake(0,0,self.frame.size.width,1000));//height越大越好,
  251. CTFrameReftextFrameForKey=CTFramesetterCreateFrame(framesetter,CFRangeMake(0,0),path,NULL);
  252. //[selfdrawFrame:textFrameForKeyinContext:nilforString:nil];
  253. CFRelease(path);
  254. CFRelease(framesetter);
  255. //CTFrameGetLineOrigins
  256. NSArray*linesArray=(NSArray*)CTFrameGetLines(textFrameForKey);
  257. CGPointorigins[[linesArraycount]];
  258. CTFrameGetLineOrigins(textFrameForKey,CFRangeMake(0,0),origins);
  259. CFArrayReflines=CTFrameGetLines(textFrameForKey);
  260. CGFloatascent;
  261. CGFloatdescent;
  262. CGFloatleading;
  263. CTLineRefline=(CTLineRef)[linesArrayobjectAtIndex:0];
  264. CTLineGetTypographicBounds(line,&ascent,&descent,&leading);
  265. //CFIndexlinesCount=CFArrayGetCount(lines);
  266. intline_y=1000-(int)origins[0].y;//第一行line的原点y坐标
  267. intline_height=line_y+(int)descent+1;//每行的高度
  268. intcurrent_line=tapLocation.y/line_height;
  269. CFIndexcurentIndex=CTLineGetStringIndexForPosition((CTLineRef)CFArrayGetValueAtIndex(lines,current_line),tapLocation);
  270. //判断超出范围
  271. if(curentIndex>[self.attributedStringlength]){
  272. return;
  273. }
  274. NSRangecurrentRange=NSMakeRange(0,[self.attributedStringlength]);
  275. //curentIndex
  276. NSDictionary*dic=[self.attributedStringattributesAtIndex:curentIndex-1effectiveRange:¤tRange];
  277. idoption=[dicvalueForKey:@"option"];
  278. if(option){
  279. if([delegaterespondsToSelector:@selector(CHLabel:tapOnKeyWord:)])
  280. {
  281. [delegateCHLabel:selftapOnKeyWord:(NSString*)[dicvalueForKey:@"option"]];
  282. }
  283. }
  284. }
  285. //获取coretext高度
  286. -(int)getAttributedStringHeightWithString:(NSAttributedString*)stringWidthValue:(int)width
  287. {
  288. inttotal_height=0;
  289. //string为要计算高度的NSAttributedString
  290. CTFramesetterRefframesetter=CTFramesetterCreateWithAttributedString((CFAttributedStringRef)string);
  291. CGRectdrawingRect=CGRectMake(0,0,width,1000);//这里的高要设置足够大
  292. CGMutablePathRefpath=CGPathCreateMutable();
  293. CGPathAddRect(path,NULL,drawingRect);
  294. CTFrameReftextFrame=CTFramesetterCreateFrame(framesetter,CFRangeMake(0,0),path,NULL);
  295. CGPathRelease(path);
  296. CFRelease(framesetter);
  297. NSArray*linesArray=(NSArray*)CTFrameGetLines(textFrame);
  298. CGPointorigins[[linesArraycount]];
  299. CTFrameGetLineOrigins(textFrame,CFRangeMake(0,0),origins);
  300. intline_y=(int)origins[[linesArraycount]-1].y;//最后一行line的原点y坐标
  301. CGFloatascent;
  302. CGFloatdescent;
  303. CGFloatleading;
  304. CTLineRefline=(CTLineRef)[linesArrayobjectAtIndex:[linesArraycount]-1];
  305. CTLineGetTypographicBounds(line,&ascent,&descent,&leading);
  306. total_height=1000-line_y+(int)descent+1;//+1为了纠正descent转换成int小数点后舍去的值
  307. CFRelease(textFrame);
  308. returntotal_height;
  309. }
  310. @end
  311. TestViewController.h代码实现:
  312. @interfaceTestViewController:UIViewController<CHLabelDelegate>
  313. {
  314. IBOutletUITextField*textString;
  315. IBOutletUITextField*keyString;
  316. }
  317. -(IBAction)showText:(id)sender;
  318. @end
  319. #import"TestViewController.h"
  320. @interfaceTestViewController()
  321. @end
  322. @implementationTestViewController
  323. -(id)initWithNibName:(NSString*)nibNameOrNilbundle:(NSBundle*)nibBundleOrNil
  324. {
  325. self=[superinitWithNibName:nibNameOrNilbundle:nibBundleOrNil];
  326. if(self){
  327. //Custominitialization
  328. }
  329. returnself;
  330. }
  331. -(IBAction)showText:(id)sender
  332. {
  333. [textStringresignFirstResponder];
  334. [keyStringresignFirstResponder];
  335. CHLabel*label=[[CHLabelalloc]initWithFrame:CGRectMake(10,260,300,200)];
  336. [labelsetUserInteractionEnabled:YES];
  337. [labelsetText:textString.textandKeyWord:keyString.text];
  338. [labelsetTextColor:[UIColorredColor]andKeyWordColor:[UIColorblueColor]];
  339. [labelsetTextUnderlineStyle:kCHLabelUnderlineStyleSingleandKeyWordUnderlineStyle:kCHLabelUnderlineStyleDouble];
  340. [labelsetTextFont:[UIFontsystemFontOfSize:20]andKeyWordFont:[UIFontboldSystemFontOfSize:30]];
  341. label.backgroundColor=[UIColorlightGrayColor];
  342. [labelsetNumberOfLines:0];
  343. label.delegate=self;
  344. NSArray*fontArray=[UIFontfamilyNames];
  345. NSString*fontName;
  346. if([fontArraycount]){
  347. fontName=[fontArrayobjectAtIndex:0];
  348. }
  349. [labelsetFont:[UIFontfontWithName:fontNamesize:20]];
  350. [self.viewaddSubview:label];
  351. //[labelsetNeedsDisplay];
  352. [labelrelease];
  353. }
  354. -(void)viewDidLoad
  355. {
  356. [superviewDidLoad];
  357. }
  358. -(void)didReceiveMemoryWarning
  359. {
  360. [superdidReceiveMemoryWarning];
  361. }
  362. #pragmamarkCHLabelDelegate
  363. -(void)CHLabel:(CHLabel*)chLabeltapOnKeyWord:(NSString*)keyWord
  364. {
  365. UIAlertView*alert=[[UIAlertViewalloc]initWithTitle:@"notice"
  366. message:[NSStringstringWithFormat:@"TaponkeyWord:%@",keyWord]
  367. delegate:nil
  368. cancelButtonTitle:@"OK"
  369. otherButtonTitles:nil];
  370. [alertshow];
  371. [alertrelease];



}



完整的项目链接:http://pan.baidu.com/share/link?shareid=362100&uk=3674861929

转载请保留,原文链接:http://blog.csdn.net/zfpp25_/article/details/8639215

若发现有不合适或错误之处,还请批评指正,不胜感激。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值