1. 程式人生 > >iOS 文字與圖片表情混排的實現

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"];

}

效果如下