用 NSAttributedString 中的图片替换微笑
Replace smiles with images in NSAttributedString
我有一个 Emoji
实体列表,每个实体都有 属性 codes
,我想检查字符串 ("]:-)"
) 是否包含其中任何一个然后用图片替换微笑。
for (Emoji *emoji in self.emojis) {
for (NSString *code in emoji.codes) {
NSString *pattern = [NSRegularExpression escapedPatternForString:code];
NSRegularExpression *regex = [[NSRegularExpression alloc] initWithPattern:pattern options:0 error:nil];
NSArray *matches = [regex matchesInString:[sourceString string] options:0 range:NSMakeRange(0, [sourceString length])];
[matches enumerateObjectsWithOptions:NSEnumerationReverse usingBlock:^(NSTextCheckingResult * _Nonnull aResult, NSUInteger idx, BOOL * _Nonnull stop) {
NSTextAttachment *attachment = [[NSTextAttachment alloc] init];
[attachment setImage:[UIImage imageNamed:emoji.image]];
NSAttributedString *replacement = [NSAttributedString attributedStringWithAttachment:attachment];
[sourceString replaceCharactersInRange:[aResult range] withAttributedString:replacement];
}];
}
}
问题是 smile with code ]:-)
包含 :-)
而我的方法将其替换为下一个: bracket ]
+ [image]
对于 :-)
,这是因为 :-)
在列表中排在第一位。
如何检查准确的字符串?
我试过:
]:-/)
、\b]:-/)\b
、/^]:-/)$/
也许有更好的解决方案可以使它正常工作。
如果我理解正确你当前的结构:
@interface Emoji : NSObject
@property (nonatomic, strong) NSString *image; //I'd expect a UIImage there and not an image name
@property (nonatomic, strong) NSArray *codes;
@end
一个可能的解决方案是使用一对值:imageName/code
@interface Emoji : NSObject
@property (nonatomic, strong) NSString *image; //I'd expect a UIImage there and not an image name
@property (nonatomic, strong) NSString *code;
@end
self.emojis
将有大量 Emoji
对象,它们可能对不同的代码具有相同的图像名称,但这样做的一个好处是这个小技巧:
以 "smaller" 个表情符号排在末尾的方式对 self.emojis
进行排序。因此,您将首先仅替换 "lengthy" 和较小的。
self.emojis = [arrayOfSingleEmojis sortedArrayUsingComparator:^NSComparisonResult(Emoji * _Nonnull emoji1, Emoji * _Nonnull emoji2) {
NSUInteger length1 = [[emoji1 code] length];
NSUInteger length2 = [[emoji2 code] length];
return [@(length2) compare:@(length1)]; //Or reverse length1 & length2, I never know, I always have to test, but I think it's the correct one
}];
因此在您当前的情况下:]:-)
将在 :-)
之前被替换,因此您应该使用 <imageFor:">:-)"]
而不是 ]<imageFor:":-)>
我有一个 Emoji
实体列表,每个实体都有 属性 codes
,我想检查字符串 ("]:-)"
) 是否包含其中任何一个然后用图片替换微笑。
for (Emoji *emoji in self.emojis) {
for (NSString *code in emoji.codes) {
NSString *pattern = [NSRegularExpression escapedPatternForString:code];
NSRegularExpression *regex = [[NSRegularExpression alloc] initWithPattern:pattern options:0 error:nil];
NSArray *matches = [regex matchesInString:[sourceString string] options:0 range:NSMakeRange(0, [sourceString length])];
[matches enumerateObjectsWithOptions:NSEnumerationReverse usingBlock:^(NSTextCheckingResult * _Nonnull aResult, NSUInteger idx, BOOL * _Nonnull stop) {
NSTextAttachment *attachment = [[NSTextAttachment alloc] init];
[attachment setImage:[UIImage imageNamed:emoji.image]];
NSAttributedString *replacement = [NSAttributedString attributedStringWithAttachment:attachment];
[sourceString replaceCharactersInRange:[aResult range] withAttributedString:replacement];
}];
}
}
问题是 smile with code ]:-)
包含 :-)
而我的方法将其替换为下一个: bracket ]
+ [image]
对于 :-)
,这是因为 :-)
在列表中排在第一位。
如何检查准确的字符串?
我试过:
]:-/)
、\b]:-/)\b
、/^]:-/)$/
也许有更好的解决方案可以使它正常工作。
如果我理解正确你当前的结构:
@interface Emoji : NSObject
@property (nonatomic, strong) NSString *image; //I'd expect a UIImage there and not an image name
@property (nonatomic, strong) NSArray *codes;
@end
一个可能的解决方案是使用一对值:imageName/code
@interface Emoji : NSObject
@property (nonatomic, strong) NSString *image; //I'd expect a UIImage there and not an image name
@property (nonatomic, strong) NSString *code;
@end
self.emojis
将有大量 Emoji
对象,它们可能对不同的代码具有相同的图像名称,但这样做的一个好处是这个小技巧:
以 "smaller" 个表情符号排在末尾的方式对 self.emojis
进行排序。因此,您将首先仅替换 "lengthy" 和较小的。
self.emojis = [arrayOfSingleEmojis sortedArrayUsingComparator:^NSComparisonResult(Emoji * _Nonnull emoji1, Emoji * _Nonnull emoji2) {
NSUInteger length1 = [[emoji1 code] length];
NSUInteger length2 = [[emoji2 code] length];
return [@(length2) compare:@(length1)]; //Or reverse length1 & length2, I never know, I always have to test, but I think it's the correct one
}];
因此在您当前的情况下:]:-)
将在 :-)
之前被替换,因此您应该使用 <imageFor:">:-)"]
而不是 ]<imageFor:":-)>