以前一直在用three20的TTStyleTextLabel,很好用,最近因为性能的问题,整个项目都不再用three20库了,想画个多色彩的layer,发现好复杂。。。UIWebView用得很是不尽人意,而且UIWebView在一次加载很多的时候性能表现也不太好,于是自己写了个layer,可以一个一个单词的定义文本颜色,目前只支持左对齐,并且可以调整词间距和行间距,根据layer的大小自动换行(wordwrapped),有兴趣的朋友可以考虑下怎么做居中对齐之类的。
大体的方法就是自己一个一个字母画。。。然后根据所用字体计算出什么时候需要换行。
/** * @file ColoredTextLayer.h * @author * @date * @version Beta 1.0 * @description * @copyright * @brief */ @interface ColoredTextLayer : CALayer{ NSMutableArray * _textNSArray; NSMutableArray * _colorNSArray; UIFont * _font; NSInteger _lineSpace; NSInteger _wordSpace; } @property (nonatomic, retain) NSMutableArray * textNSArray; @property (nonatomic, retain) NSMutableArray * colorNSArray; @property (nonatomic, retain) UIFont * font; @property (nonatomic, assign) NSInteger lineSpace; @property (nonatomic, assign) NSInteger wordSpace; /*! * set the layer colored text */ - (void)setTexts:(NSArray *)texts inColors:(NSArray *)colors withFont:(UIFont *)font lineSpace:(NSInteger)lSpace wordSpace:(NSInteger)wSpace; /*! * separate the string to words */ - (void)initTextsColorsArray:(NSArray *)texts inColors:(NSArray *)colors; @end
/** * @file ColoredTextLayer.m * @author * @date * @version Beta 1.0 * @description * @copyright * @brief */ #import "ColoredTextLayer.h" #import "ColoredTextLayerDelegate.h" @implementation ColoredTextLayer @synthesize textNSArray = _textNSArray; @synthesize colorNSArray = _colorNSArray; @synthesize font = _font; @synthesize lineSpace = _lineSpace; @synthesize wordSpace = _wordSpace; /*! * @override */ - (id)init { self = [super init]; if (self) { [self.delegate release]; self.delegate = nil; ColoredTextLayerDelegate * delegate = [[ColoredTextLayerDelegate alloc] init]; self.delegate = delegate; _textNSArray = [[NSMutableArray alloc] initWithCapacity:0]; _colorNSArray = [[NSMutableArray alloc] initWithCapacity:0]; } return self; } /*! * set the layer colored text * @param texts texts array * @param colors colors array * @param font font * @param lSpace space size between two lines * @param wSpace space size between two words * @return null */ - (void)setTexts:(NSArray *)texts inColors:(NSArray *)colors withFont:(UIFont *)font lineSpace:(NSInteger)lSpace wordSpace:(NSInteger)wSpace { [self initTextsColorsArray:texts inColors:colors]; _font = font; _lineSpace = lSpace; _wordSpace = wSpace; [self setNeedsDisplay]; } /*! * separate the string to words * @param texts texts array * @param colors colors array * @return null */ - (void)initTextsColorsArray:(NSArray *)texts inColors:(NSArray *)colors { for (int i = 0; i < texts.count; i++) { NSString * string = [texts objectAtIndex:i]; UIColor * color = [colors objectAtIndex:i]; NSArray * array = [string componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]; array = [array filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"SELF != ''"]]; for (int i = 0; i < array.count; i++) { [_textNSArray addObject:[array objectAtIndex:i]]; [_colorNSArray addObject:color]; } } } /*! * @override */ - (void)dealloc { [_textNSArray release]; [_colorNSArray release]; [super dealloc]; } @end
/** * @file ColoredTextLayer.h * @author * @date * @version Beta 1.0 * @description * @copyright * @brief */ @interface ColoredTextLayerDelegate : NSObject { CGPoint _cursor; } @end
/** * @file ColoredTextLayer.h * @author * @date * @version Beta 1.0 * @description * @copyright * @brief */ #import "ColoredTextLayerDelegate.h" #import "ColoredTextLayer.h" @implementation ColoredTextLayerDelegate /*! * @override */ - (id)init { self = [super init]; if (self) { _cursor = CGPointMake(0, 0); } return self; } /*! * @override */ - (void)drawLayer:(CALayer *)layer inContext:(CGContextRef)ctx { UIGraphicsPushContext(ctx); if ([layer isKindOfClass:[ColoredTextLayer class]]) { ColoredTextLayer * coloredLayer = (ColoredTextLayer *)layer; for (int i = 0; i < coloredLayer.textNSArray.count; i++) { NSString * string = [coloredLayer.textNSArray objectAtIndex:i]; UIColor * color = [coloredLayer.colorNSArray objectAtIndex:i]; CGSize size = [string sizeWithFont:coloredLayer.font]; NSInteger restWidth = coloredLayer.frame.size.width - _cursor.x; NSInteger restHeight = coloredLayer.frame.size.height - _cursor.y; [color setFill]; if (size.width <= restWidth && size.height < restHeight) { //can draw in current line CGSize stringSize = [string drawAtPoint:_cursor withFont:coloredLayer.font]; _cursor.x = _cursor.x + stringSize.width + coloredLayer.wordSpace; } else if (size.width > restWidth && size.height * 2 < restHeight) { //can draw in next line _cursor.x = 0; _cursor.y = _cursor.y + size.height + coloredLayer.lineSpace; CGSize stringSize = [string drawAtPoint:_cursor withFont:coloredLayer.font]; _cursor.x = _cursor.x + stringSize.width + coloredLayer.wordSpace; } else { return; } } } UIGraphicsPopContext(); } @end