CoreText是專門用來處理文字和字體的底層技術(shù)篮赢。直接和2D 圖形渲染引擎打交道郎笆。效率非常高。 先看實(shí)戰(zhàn)效果https://github.com/FSilver/FWDrawView

第一步:配置Config
@interface FWDrawConfig : NSObject
@property(nonatomic,strong)NSString *text;
@property(nonatomic,assign)CGFloat width;
@property(nonatomic,assign)UIFont *font;
@property(nonatomic,strong)UIColor *textColor;
@property(nonatomic,strong)UIColor *linkColor;
@property(nonatomic,assign)int underLineOfLink;
@property(nonatomic,assign)NSInteger numberOfLines;
@property(nonatomic,assign)UIEdgeInsets edgInsets;
@end
拿到文本后,先設(shè)置文本最大的顯示寬度脚作,文本的字體警没,顏色匈辱,文字最大顯示行數(shù),文字在控件中上下左右邊距杀迹。 鏈接字體的顏色亡脸,下劃線。
第二步:解析parse
@interface FWDrawParser : NSObject
@property(nonatomic,strong)FWDrawInfo *data;
@property(nonatomic,strong)NSMutableAttributedString *resultAttributeString;
@property(nonatomic,strong)NSDictionary *textAttributeDict;
-(id)initWithConfig:(FWDrawConfig*)config;
-(void)parseEmoji;
-(void)parseUrl;
-(void)parsePhone;
-(void)addLinkWithValue:(id)value range:(NSRange)range;
@end
利用config生成富文本字典树酪,以及富文本呢
-(void)configTextAttributeDictionay
{
//用一個普通的漢子排版的高度浅碾,設(shè)置為最低高度,保證中文续语,英文垂谢,表情,間距相等疮茄,視覺上舒服
//float minLineHight = config.font.lineHeight - config.font.descender;
float minLineHight = _config.font.lineHeight;
NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];
[paragraphStyle setLineSpacing:0];
[paragraphStyle setMinimumLineHeight:minLineHight];
paragraphStyle.lineHeightMultiple = 0;
NSDictionary *ats = @{
NSFontAttributeName : _config.font,
NSForegroundColorAttributeName:_config.textColor,
NSParagraphStyleAttributeName : paragraphStyle,
};
_textAttributeDict = ats;
}
-(void)configResultAttributeString
{
_resultAttributeString = [[NSMutableAttributedString alloc]init];
NSAttributedString *attributeString = [[NSAttributedString alloc]initWithString:_config.text attributes:_textAttributeDict];
[_resultAttributeString appendAttributedString:attributeString];
}
第三步:數(shù)據(jù)data
@interface FWDrawInfo : NSObject
@property(nonatomic,assign)CTFrameRef ctFrame;
@property(nonatomic,assign)CGFloat originHeight; //全部顯示完全的高度
@property(nonatomic,assign)CGFloat width; //實(shí)際寬度
@property(nonatomic,assign)CGFloat height; //實(shí)際高度
@property(nonatomic,assign)NSInteger lines; //文本總行數(shù)
@property(nonatomic,assign)NSInteger numberOfLines; //限制行數(shù)
@property(nonatomic,assign)UIEdgeInsets edgInsets;
@property(nonatomic,strong)NSDictionary *textAttributeDict;
@property(nonatomic,strong)NSAttributedString *attributedString;
@property(nonatomic,strong)NSArray *emojiArray; //賦值的時候滥朱,計(jì)算區(qū)域
@property(nonatomic,strong)NSArray *linkArray; //賦值的時候,計(jì)算區(qū)域
@end
第四步:繪制data
@class FWDrawView;
@protocol FWDrawViewDelegate <NSObject>
@optional
-(void)didClickFWDraw:(FWDrawView*)draw; //單擊
-(void)didLongPressFWDraw:(FWDrawView*)draw;//雙擊
-(void)didClickFWDraw:(FWDrawView *)draw byLink:(FWDrawLinkInfo*)link; //點(diǎn)擊鏈接
@end
@interface FWDrawView : UIView
@property(nonatomic,weak)id<FWDrawViewDelegate>delegate;
@property(nonatomic,strong)FWDrawInfo *data;
@property(nonatomic,strong)UIColor *linkBgColor;//選中鏈接后力试,鏈接背景色
@property(nonatomic,strong)UIColor *tapColor; //點(diǎn)擊View,高亮色
@property(nonatomic,assign)BOOL allowTapGesture; //是否允許單機(jī)
@property(nonatomic,assign)BOOL allowLongPressGesture; //是否允許長按
@property(nonatomic,strong)UIColor *longPressColor; //長按View后焚虱,view的背景色
@end
繪制方法
-(void)drawRect:(CGRect)rect
{
[super drawRect:rect];
if(self.data == nil){
return;
}
CGContextRef context = UIGraphicsGetCurrentContext();
//坐標(biāo)系coreText --》 UIkit坐標(biāo)系
CGContextSetTextMatrix(context, CGAffineTransformIdentity);
CGContextTranslateCTM(context, 0, self.bounds.size.height);
CGContextScaleCTM(context, 1.0, -1.0);
_lastLineOriginY = -1;
_lastLineRightX = -1;
if(_data.numberOfLines == 0 || _data.numberOfLines >= _data.lines){
CTFrameDraw(self.data.ctFrame, context);
}else{
[self drawLineByContext:context];
}
//作用是,畫表情
for (FWDrawEmojiInfo * emoji in self.data.emojiArray) {
//轉(zhuǎn)為UI坐標(biāo)系,表情位置大于有效區(qū)域懂版,就break
float y = _data.height - emoji.drawRect.origin.y - emoji.drawRect.size.height;
if(y + emoji.drawRect.size.height > _data.height - _data.edgInsets.bottom){
break;
}
BOOL drawImage = NO;
if(_lastLineOriginY == -1 && _lastLineRightX == -1){
//全部顯示
drawImage = YES;
}else{
//限制行數(shù)
if(y < _lastLineOriginY){
//不是最后一行
drawImage = YES;
}else if(emoji.drawRect.origin.x + emoji.drawRect.size.width < _lastLineRightX){
//是最后一行
drawImage = YES;
}
}
if(drawImage){
UIImage *image = [UIImage imageNamed:emoji.imageName];
if(image){
CGContextDrawImage(context, emoji.drawRect, image.CGImage);
}
}
}
//作用是鹃栽,選中鏈接后,鏈接高亮顯示
for (FWDrawLinkInfo *url in self.data.linkArray) {
for (NSValue *value in url.drawRectArray) {
//轉(zhuǎn)為UI坐標(biāo)系
CGRect urlRect = [value CGRectValue];
CGFloat y = _data.height - urlRect.origin.y - urlRect.size.height;
if( y + urlRect.size.height > _data.height - _data.edgInsets.bottom){
break;
}
if(url.isSelected){
CGRect urlRect = [value CGRectValue];
CGContextSetFillColorWithColor(context,self.linkBgColor.CGColor);
CGContextFillRect(context , urlRect);
}
}
}
}
完整代碼github地址 https://github.com/FSilver/FWDrawView