以前一直在用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