类似QQ聊天图文混排
第一次要用到图文混排的时候,感觉很难。虽然知道drawRect可以实现,但是对这块了解的较少,无法实现。后来研究了一下:
drawRect就像是在画布是画画一样,用两个变量标注坐标,左上角为起点,把文字和表情一个一个的“画”上去就OK了
#define BEGIN_TAG @"[" #define END_TAG @"]" #define WORD_SIZE 17.0f #define SPACE_LINE 3.0f #define SPACE_WORD 2.0f @interface AttributedLabel () { CGFloat _upX, _upY; // 可变指针 CGRect _contentRect; UIFont *_font; UIColor *_textColor; NSMutableDictionary *_dict; } -(void)setText:(NSString *)text { _text = text; [self setNeedsDisplay] } 1.初始化 - (id)initWithFrame:(CGRect)frame { if (self = [super initWithFrame:frame]) { [self startLayout]; } return self; } 2.设置Attributes - (void)startLayout { self.backgroundColor = [UIColor cyanColor]; UIFont *font = [UIFont fontWithName:@"ArialMT" size:WORD_SIZE]; _textColor = [UIColor blackColor]; if (_dict == nil) { _dict = [NSMutableDictionary new]; } [_dict setObject:_font forKey:NSFontAttributeName]; [_dict setObject:_textColor forKey:NSForegroundColorAttributeName]; } 3.重绘,开始在画布上画文本和表情 - (void)drawRect:(CGRect)rect { if (_text == nil || [_text isEqualToString:@""]) { return; } // 初始化数据 // 开始画 _contentRect = CGRectMake(_contentInsets.left, _contentInsets.top, rect.size.width- _contentInsets.left-_contentInsets.right, rect.size.height-_contentInsets.top-_contentInsets.bottom); _upX = _contentRect.origin.x; _upY = _contentRect.origin.y; NSRange startRange = [_text rangeOfString:BEGIN_TAG]; if (startRange.location != NSNotFound) { NSMutableString *tmpString = [_text mutableCopy]; while (tmpString.length != 0) { startRange = [tmpString rangeOfString:BEGIN_TAG]; if (startRange.location == NSNotFound) { [self drawText:tmpString]; break; } NSString *textStr = [tmpString substringToIndex:startRange.location]; [self drawText:textStr]; [tmpString deleteCharactersInRange:NSMakeRange(0, startRange.location+startRange.length)]; NSRange endRange = [tmpString rangeOfString:END_TAG]; NSString *face = [tmpString substringToIndex:endRange.location]; UIImage *faceImage = [self getIamgeFromName:face]; // 根据名字获取image [self drawImage:faceImage withSize:CGSizeMake(WORD_SIZE, WORD_SIZE)]; [tmpString deleteCharactersInRange:NSMakeRange(0, endRange.location+endRange.length)]; } }else { // 没有表情直接画 [_text drawInRect:_contentRect withAttributes:_dict]; } } 4.自定义两个方法:画文本和话表情 - (void)drawText:(NSString *)str { for (int index=0; index<str.length; index++) { NSMutableString *temp = [[str substringWithRange:NSMakeRange(index, 1)] mutableCopy]; // 简单的实现,字母、数字和汉字的大小不一样,固定的WORD_SIZE会使得英文单词间隔比较大 /************************************************************************************** unichar charItem = [temp characterAtIndex:0]; if ((charItem <= 'z' && charItem >= 'a')||(charItem <= 'Z' && charItem >= 'A')) { while (index <str.length-1) { charItem = [str characterAtIndex:index+1]; if ((charItem <= 'z' && charItem >= 'a')||(charItem <= 'Z' && charItem >= 'A')) { [temp appendFormat:@"%c",charItem]; index++; } else{ break; } } } **************************************************************************************/ if ([temp isEqualToString:@"\n"]) { _upX = _contentRect.origin.x; _upY += (WORD_SIZE + SPACE_LINE); continue; } if (_upX+WORD_SIZE > _contentRect.size.width) { _upX = _contentRect.origin.x; _upY += (WORD_SIZE + SPACE_LINE); } [temp drawInRect:CGRectMake(_upX, _upY, WORD_SIZE, WORD_SIZE+2) withAttributes:_dict]; _upX += WORD_SIZE; } } - (void)drawImage:(UIImage *)image withSize:(CGSize)size { if (_upX+size.width > _contentRect.size.width) { _upX = _contentRect.origin.x; _upY += (WORD_SIZE + SPACE_LINE); } [image drawInRect:CGRectMake(_upX, _upY, size.width, size.height)]; _upX += (size.width + SPACE_WORD); }