【问题标题】:Replace smiles with images in NSAttributedString用 NSAttributedString 中的图像替换微笑
【发布时间】:2019-02-11 19:59:06
【问题描述】:

我有一个 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];
        }];
    }
}

问题是带有代码]:-) 的微笑包含:-) 并且我的方法将其替换为下一个:括号 ] + [image] for :-),这是因为@987654330 @ 在列表中排在第一位。

如何检查确切的字符串?

我试过了: ]:-/)\\b]:-/)\\b/^]:-/)$/

也许有更好的解决方案来实现这一点。

【问题讨论】:

  • 是否可以发布一个包含这些微笑的字符串示例?
  • 当然,只是微笑
  • 如果只是一个微笑,那么你可以有一个字典,其中键是微笑,值是图像(或图像名称)。然后你可以做类似let image: UIImage? = smiles[smile] 的事情,再加上不断查找时间的好处。
  • 每个表情符号对象可以有几个代码。例如,happy = ":)"、":-)" 等。
  • 快速修复想法:不要使用NSDictionary,使用单个字典的 NSArray(或具有属性“stringEmoji”和另一个“imageName”的小对象。以一种方式对其进行排序最后是“较小”的表情符号,可以包含在多个表情符号中。

标签: ios objective-c regex nsstring


【解决方案1】:

如果我正确理解了您当前的结构:

@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 对象,它们可能具有不同代码的相同图像名称,但这样做的好处是这个小技巧:
self.emojis 进行排序,以使“较小”的表情符号位于末尾。因此,您将首先只替换“长”的和较小的。

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:":-)>

【讨论】:

猜你喜欢
  • 2013-11-18
  • 1970-01-01
  • 2012-01-04
  • 2016-12-10
  • 1970-01-01
  • 2014-04-26
  • 1970-01-01
  • 2018-12-14
  • 1970-01-01
相关资源
最近更新 更多