类似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);
}

 

posted on 2015-11-12 11:13  rgshio  阅读(406)  评论(0编辑  收藏  举报

导航