如何在使用NSAttributedString添加照片后从UITextView中检索照片?

Lau*_*fan 7 objective-c uitextview nsattributedstring ios

我正在使用下一个代码将图像添加到UITextView:

    UITextView *textView = [[UITextView alloc] initWithFrame:CGRectMake(200,200,140,140)];
    textView.font = [UIFont systemFontOfSize:20.0f];
    NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:@"Test  with emoji"];
    NSTextAttachment *textAttachment = [[NSTextAttachment alloc] init];
    textAttachment.image = [UIImage imageNamed:@"Angel.png"];

    //for the padding inside the textView
    textAttachment.image = [UIImage imageWithCGImage:textAttachment.image.CGImage scale:3.0 orientation:UIImageOrientationUp];
    NSAttributedString *attrStringWithImage = [NSAttributedString attributedStringWithAttachment:textAttachment];
    [attributedString replaceCharactersInRange:NSMakeRange(5, 1) withAttributedString:attrStringWithImage];
    [attributedString addAttribute:NSFontAttributeName value:[UIFont systemFontOfSize:17] range:NSMakeRange(0, attributedString.length)];
    textView.attributedText = attributedString;
    NSLog(@"Text view: %@", textView.attributedText);

    [self.view addSubview:textView];
Run Code Online (Sandbox Code Playgroud)

结果如下:

在此输入图像描述

我感兴趣的是,我怎么知道在文本字段和巫婆位置插入了什么图片?我正在考虑使用attributedText,因为你可以在代码中观察,因为它记录:

Text view: Test {
    NSFont = "<UICTFont: 0x7ff0324f2110> font-family: \".HelveticaNeueInterface-Regular\"; font-weight: normal; font-style: normal; font-size: 17.00pt";
}?{
    NSAttachment = "<NSTextAttachment: 0x7ff032682bc0>";
    NSFont = "<UICTFont: 0x7ff0324f2110> font-family: \".HelveticaNeueInterface-Regular\"; font-weight: normal; font-style: normal; font-size: 17.00pt";
}with emoji{
    NSFont = "<UICTFont: 0x7ff0324f2110> font-family: \".HelveticaNeueInterface-Regular\"; font-weight: normal; font-style: normal; font-size: 17.00pt";
} 
Run Code Online (Sandbox Code Playgroud)

更新

使用代码检索图像:

NSMutableArray *imagesArray = [[NSMutableArray alloc] init];
    [attributedString enumerateAttribute:NSAttachmentAttributeName
                                 inRange:NSMakeRange(0, [attributedString length])
                                 options:0
                              usingBlock:^(id value, NSRange range, BOOL *stop)
    {
        if ([value isKindOfClass:[NSTextAttachment class]])
        {
            NSTextAttachment *attachment = (NSTextAttachment *)value;
            UIImage *image = nil;
            if ([attachment image])
                image = [attachment image];
            else
                image = [attachment imageForBounds:[attachment bounds]
                                     textContainer:nil
                                    characterIndex:range.location];

            if (image)
                [imagesArray addObject:image];
        }
    }];
Run Code Online (Sandbox Code Playgroud)

但是如果attributionString包含超过1张连续照片怎么办?例:

  • 如果该字符串包含两个连续的照片,则只有一个照片添加到数组中

在此输入图像描述

NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:@"Test   with emoji "];
    [attributedString replaceCharactersInRange:NSMakeRange(4, 1) withAttributedString:attrStringWithImage];
    [attributedString replaceCharactersInRange:NSMakeRange(5, 1) withAttributedString:attrStringWithImage];
Run Code Online (Sandbox Code Playgroud)

日志:

Image array: (
    "<UIImage: 0x7fd4e3e56760>"
)
Run Code Online (Sandbox Code Playgroud)
  • 如果照片不连续,则它们都会正确地添加到数组中

在此输入图像描述

NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:@"Test  with emoji "];
[attributedString replaceCharactersInRange:NSMakeRange(4, 1) withAttributedString:attrStringWithImage];
    [attributedString replaceCharactersInRange:NSMakeRange(16, 1) withAttributedString:attrStringWithImage];
Run Code Online (Sandbox Code Playgroud)

日志

Image array: (
    "<UIImage: 0x7f9ce35a4a70>",
    "<UIImage: 0x7f9ce35a4a70>"
)
Run Code Online (Sandbox Code Playgroud)

那么,我正在做什么或使用enumerateAttribute方法有一个错误?

更新2 管理,如果我创建了一个新的解决问题textAttachmentattrStringWithImage实例每张照片我补充.

Lar*_*rme 3

此处解释了检索图像。

您的新问题是,如果两个图像连续且相同。

所以而不是:

if (image)
    [imagesArray addObject:image];
Run Code Online (Sandbox Code Playgroud)

您需要进行其他检查,这适用于两个图像,但您无法知道它们是否连续。

if (image)
{
    if ([imagesArray lastObject] != image)
        [imagesArray addObject:image];
}
Run Code Online (Sandbox Code Playgroud)

所以你也需要保留参考文献NSRange

if (image)
{
    if ([imagesArray count] > 0)
    {
        NSDictionary *lastFound = [imagesArray lastObject];
        NSRange lastRange = [lastFound[@"range"] rangeValue];
        UIImage *lastImage = lastFound[@"image"];
        if (lastImage == image && lastRange.location+lastRange.length == range.location)
        { //Two images same & consecutive}
        else
        {
            [imagesArray addObject:@{@"image":image, @"range":[NSValue valueWithRange:range]}];
        }
    }
    else
    {
        [imagesArray addObject:@{@"image":image, @"range":[NSValue valueWithRange:range]}];
    }
}
Run Code Online (Sandbox Code Playgroud)

仅检索图像:

NSArray *onlyImages = [imagesArray valueForKey:@"image"];
Run Code Online (Sandbox Code Playgroud)

注意:我没有检查这段代码是否可以编译,但您应该了解整个想法。我的范围计算可能是错误的(缺少一些+1/-1,但通过测试验证并不困难),如果两个相同的连续图像之间有空格怎么办?您可能想要获取 ( 之间的字符串NSString *stringBetween = [[attributedString string] substringWithRange:NSMakeRange(lastRange.location+lastRange.length, range.location-lastRange.location+lastRange.length)],并检查空格、标点字符(有很多方法可以做到这一点)。

附加说明:就您而言,仅比较image != newImage可能就足够了,但如果您使用网络图像,或者甚至在捆绑包中使用两个名称不同但相同的图像,那么了解它们是否相同是另一个问题。关于比较两个图像有一些问题,但这应该需要一些时间/资源。