iOS 文字與圖片表情混排的實現
2015-09-04 by 木易哥哥
智者精選,每天獲取勵志認知能量 www.5izhjx.com
要實現文圖混排效果需要用到的有:富文字NSMutableAttributedString,字元替換substringWithRange,以及支援動畫gif的ImageIO.h。
寫了幾個物件TQRichTextView,TQRichTextRunEmoji,SvGifView,廢話不多說,列出實現該效果的幾個核心程式碼塊。
TQRichTextView.m,
if (richTextRun.drawSelf)
{
//動態圖片 begin
CGFloat runPointX = runRect.origin.x + lineOrigin.x;
CGFloat runPointY = self.frame.size.height- lineOrigin.y-15 ;
CGRect runRectDraw = CGRectMake(runPointX, runPointY, 18, 18);
[self drawRunWithRect:runRectDraw emojiString:richTextRun.text];//動態圖片,add by edward yang
[self.runRectDictionary setObject:richTextRun forKey:[NSValue valueWithCGRect:runRectDraw]];
}
else
{
if (richTextRun)
{
[self.runRectDictionary setObject:richTextRun forKey:[NSValue valueWithCGRect:runRect]];
}
}
- (void)drawRunWithRect:(CGRect)rect emojiString:(NSString*)emojiString
{
NSURL *fileUrl = [[NSBundle mainBundle] URLForResource:emojiString withExtension:@"gif"];
_gifView = [[SvGifView alloc] initWithCenter:rect fileURL:fileUrl];
_gifView.backgroundColor = [UIColor clearColor];
_gifView.autoresizingMask = UIViewAutoresizingFlexibleBottomMargin | UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin;
[self addSubview:_gifView];
[_gifView startGif];
}
TQRichTextRunEmoji.m+ (NSArray *) emojiStringArray
{
return [NSArray arrayWithObjects:@"[微笑]",@"[撇嘴]",@"[色]",@"[發呆]",@"[得意]",@"[害羞]",@"[閉嘴]",@"[睡]",@"[大哭]",@"[尷尬]",@"[發怒]",@"[調皮]",@"[呲牙]",@"[驚訝]",@"[難過]",@"[酷]",@"[冷汗]",@"[抓狂]",@"[吐]",@"[偷笑]",@"[白眼]",@"[傲慢]",@"[飢餓]",@"[困]",@"[驚恐]",@"[流汗]",@"[憨笑]",@"[奮鬥]",@"[疑問]",@"[噓]",@"[暈]",@"[衰]",@"[骷髏]",@"[敲打]",@"[再見]",@"[摳鼻]",@"[鼓掌]",@"[糗大了]",@"[壞笑]",@"[左哼哼]",@"[右哼哼]",@"[哈欠]",@"[鄙視]",@"[委屈]",@"[快哭了]",@"[陰險]",@"[親親]",@"[嚇]",@"[可憐]",@"[菜刀]",@"[西瓜]",@"[啤酒]",@"[籃球]",@"[乒乓]",@"[咖啡]",@"[飯]",@"[豬頭]",@"[玫瑰]",@"[凋謝]",@"[示愛]",@"[愛心]",@"[心碎]",@"[蛋糕]",@"[閃電]",@"[炸彈]",@"[紅包]",@"[足球]",@"[瓢蟲]",@"[便便]",@"[月亮]",@"[太陽]",@"[禮物]",@"[再見]",@"[擁抱]",@"[強]",@"[弱]",@"[握手]",@"[抱拳]",@"[勾引]",@"[拳頭]",@"[差勁]",@"[愛你]",@"[NO]",@"[OK]",nil];
}
+ (NSArray *)runsForAttributedString:(NSMutableAttributedString *)attributedString
{
NSString *markL = @"[";
NSString *markR = @"]";
NSString *string = attributedString.string;
NSMutableArray *array = [NSMutableArray array];
NSMutableArray *stack = [[NSMutableArray alloc] init];
for (int i = 0; i < string.length; i++)
{
NSString *s = [string substringWithRange:NSMakeRange(i, 1)];
//NSLog(@"s:%@",s);
if (([s isEqualToString:markL]) || ((stack.count > 0) && [stack[0] isEqualToString:markL]))
{
if (([s isEqualToString:markL]) && ((stack.count > 0) && [stack[0] isEqualToString:markL]))
{
[stack removeAllObjects];
}
//NSLog(@"stack:%@",stack);
[stack addObject:s];
if ([s isEqualToString:markR] || (i == string.length - 1))
{
NSMutableString *emojiStr = [[NSMutableString alloc] init];
for (NSString *c in stack)
{
[emojiStr appendString:c];
}
//NSLog(@"emojiStr:%@",emojiStr);
if ([[TQRichTextRunEmoji emojiStringArray] containsObject:emojiStr])
{
NSRange range = NSMakeRange(i + 1 - emojiStr.length, emojiStr.length);
[attributedString replaceCharactersInRange:range withString:@" "];
TQRichTextRunEmoji *run = [[TQRichTextRunEmoji alloc] init];
run.range = NSMakeRange(i + 1 - emojiStr.length, 1);
run.text = emojiStr;
run.drawSelf = YES;
[run decorateToAttributedString:attributedString range:run.range];
[array addObject:run];
i = i -emojiStr.length; //代替多少,後退多少,add by edward yang
}
[stack removeAllObjects];
}
}
}
return array;
}
SVGifView.m- (void)startGif
{
CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:@"contents"];
NSMutableArray *times = [NSMutableArray arrayWithCapacity:3];
CGFloat currentTime = 0;
int count = _frameDelayTimes.count;
for (int i = 0; i < count; ++i) {
[times addObject:[NSNumber numberWithFloat:(currentTime / _totalTime)]];
currentTime += [[_frameDelayTimes objectAtIndex:i] floatValue];
}
[animation setKeyTimes:times];
NSMutableArray *images = [NSMutableArray arrayWithCapacity:3];
for (int i = 0; i < count; ++i) {
[images addObject:[_frames objectAtIndex:i]];
}
[animation setValues:images];
[animation setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear]];
animation.duration = _totalTime;
animation.delegate = self;
animation.repeatCount = HUGE_VALF;
[self.layer addAnimation:animation forKey:@"gifAnimation"];
}
效果如下