另一种思路:在最后一个位置开始往前替换更改图片
#import "ViewController.h"
#import "NSString+RegularExpression.h"
#import "ZTextAttachment.h"
@interface ViewController ()
@property (weak, nonatomic) IBOutlet UILabel *label;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.label.text = @"[smiley_29]召召, 你的肥皂[smiley_2]丢了吗?[smiley_6]";
}
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
/*================= 将文字替换成表情 =================*/
NSString *content = self.label.text;
// 1. 查找符合条件的文本 , 正则
// \[\w+\] 由于[]在正则中是特殊语法, 因此使用 \[ 和 \] 来表示普通的[或]文本
NSString *pattern = @"\\[\\w+\\]";
// [图片名] 在 整句话当中的Range
NSArray <NSValue *> *rangeArray = [content matchesRangeWithPattern:pattern];
// content的富文本 (原始的)
NSMutableAttributedString *attrContent = [[NSMutableAttributedString alloc] initWithString:content];
// 对每一个文字进行替换
// lengthChanged 来记录 富文本替换表情后长度的变化
NSUInteger totalLengthChanged = 0;
for (NSValue *value in rangeArray) {
/*================= Content - NSString =================*/
// [smiley_29]召召, 你的肥皂[smiley_2]丢了吗?[smiley_6]
// 1. 获取图片
NSRange range = value.rangeValue;
NSString *imagename = [content substringWithRange:NSMakeRange(range.location + 1, range.length -2)];
UIImage *image = [UIImage imageNamed:imagename];
// 2. 创建对应图片的富文本, 长度为1
ZTextAttachment *attachment = [[ZTextAttachment alloc] init];
attachment.image = image;
NSAttributedString *imageAttrString = [NSAttributedString attributedStringWithAttachment:attachment];
/*================= AttrContent - NSTextAttributeString =================*/
// (表情)召召, 你的肥皂[smiley_2]丢了吗?[smiley_6]
NSUInteger originalLength = attrContent.length; // 改变前长度
// 计算前的Range值
NSRange newRange = NSMakeRange(range.location - totalLengthChanged, range.length);
[attrContent replaceCharactersInRange:newRange withAttributedString:imageAttrString];
NSUInteger finalLength = attrContent.length; // 改变后的长度
NSUInteger lengthChanged = originalLength - finalLength; // 这一次图片替换长度的改变
totalLengthChanged += lengthChanged; // 累加每一次的改变
}
[self.label setAttributedText:attrContent];
}
@end
#import <UIKit/UIKit.h>
@interface ZTextAttachment : NSTextAttachment
@end
#import "ZTextAttachment.h"
@implementation ZTextAttachment
// 返回附件(例子是图片)的Bounds
- (CGRect)attachmentBoundsForTextContainer:(NSTextContainer *)textContainer proposedLineFragment:(CGRect)lineFrag glyphPosition:(CGPoint)position characterIndex:(NSUInteger)charIndex
{
// lineFrag 代表附近所在的文字所占的Rect值
return CGRectMake(0, -lineFrag.size.height * 0.2, lineFrag.size.height, lineFrag.size.height);
}
@end