Download 替换NSMutableAttributeString上的NSTextattachement图像

Download 替换NSMutableAttributeString上的NSTextattachement图像,download,uitextview,textkit,nstextstorage,nstextattachment,Download,Uitextview,Textkit,Nstextstorage,Nstextattachment,我正在构建一个包含文本和图像的UITextView(将NSTextstorage子类化以显示我的内容) 我有图片和URL的文本内容。 所以我的问题是,如果没有缓存,我需要下载所有的图像 所以我想先插入一个占位符图像,下载图像,然后用下载的图像替换占位符图像 以下是我的工作方式。 首先,我使用图像url格式化文本,方法是将所有url替换为此标记: [IMG]url[/IMG] 然后我用正则表达式得到所有这些标签 我正在测试是否存在缓存图像。如果没有,我将提取所有URL,下载并缓存它们 我创建了一

我正在构建一个包含文本和图像的UITextView(将NSTextstorage子类化以显示我的内容)

我有图片和URL的文本内容。 所以我的问题是,如果没有缓存,我需要下载所有的图像

所以我想先插入一个占位符图像,下载图像,然后用下载的图像替换占位符图像

以下是我的工作方式。

首先,我使用图像url格式化文本,方法是将所有url替换为此标记:

[IMG]url[/IMG]
然后我用正则表达式得到所有这些标签

我正在测试是否存在缓存图像。如果没有,我将提取所有URL,下载并缓存它们

我创建了一个NSObject类ImageCachingManager,并声明了一个在下载图像时调用的委托方法:

@protocol ImageCachingManagerDelegate <NSObject>

- (void)managerDidCacheImage:(UIImage *)image forUrl:(NSString *)url;

@end
@protocol-ImageCachingManagerDelegate
-(void)managerdCacheImage:(UIImage*)image for url:(NSString*)url;
@结束
这样,我就可以使用委托方法获得的图像的url在我的NSTextstorage attributedString中搜索匹配的url,并用下载的图像替换当前的NSTextattachement图像

但我不知道怎么做


谢谢你的帮助

我目前正在做类似的事情,我认为这可能会有所帮助。代码非常简单,但希望它能让您进入下一步-我将逐步介绍:

整个周期 1.使用regex或XPath在全文中查找图像标记-我个人认为Hppl功能更强大,但如果您的内容结构良好且可靠,regex可能很好

  • 将此匹配的空格减少到1个字符并存储该范围-textAttachment在textview中仅占用1个字符的空间,因此最好将其减少到1,否则,当您用第一个textAttachment替换范围中的第一个字符匹配时,下一个范围标记将过期,这将导致问题。这是一个重要的步骤,我必须对文本进行大量的处理,在解析过程中,范围会发生变化,因此我创建了一个特殊字符数组,我知道这些字符永远不会出现在输入中,并将它们放入保留空间,同时,我将这个特殊字符和图像的src存储在一个非常简单的NSObject子类数组中,该子类存储特殊字符,ImgSrc plus为NSRange留出了空间,但我基本上会在稍后的过程中再次找到特殊字符,因为从这一点开始它就被移动了,然后在处理的最后设置NSRange-在您的情况下,这可能不是必需的,但原理是相同的;您需要一个带有NsRange(将成为文本附件)和imgSource的自定义对象

  • 循环此数组,将占位符图像附件添加到属性字符串中。您可以通过添加透明图像或“加载”图像来完成此操作。您还可以在此期间检查缓存中是否存在现有图像,如果占位符存在于缓存中,则跳过该占位符

  • 成功下载映像后,您需要使用代理将当前附件替换为新附件。通过替换对象中已存储的区域中的占位符。使用NSTextAttachment创建占位符AttributeString,然后替换该范围,如下所示

  • 一些示例代码:

    步骤1和2:

            specialCharsArray = [[NSArray alloc]initWithObjects:@"Û", @"±", @"¥", @"å", @"æ", @"Æ", @"Ç", @"Ø", @"õ", nil];
    
    //使用Hppl

    NSString *allImagesXpathQueryString = @"//img/@src";
    NSArray *imageArray = [bodyTextParser searchWithXPathQuery:allImagesXpathQueryString];
        //
    
        imageRanges = [[NSMutableArray alloc] init];
    
        if([imageArray count]){
            for (TFHppleElement *element in imageArray) {
                int i = 0;
                NSString *imgSource = [[[element children] objectAtIndex:0] content];
    
                NSString *replacementString = [specialCharsArray objectAtIndex:i];
                UIImage *srcUIImage = [UIImage imageNamed:imgSource];
    
                [srcUIImage setAccessibilityIdentifier:imgSource]; //only needed if you need to reference the image filename later as it's lost in a UIImage if stored directly
    
    //imagePlacement是NSObject子类,用于存储上述范围、替换和图像

        imagePlacement *foundImage = [[imagePlacement alloc]init] ;
    
    
                [foundImage initWithSrc:srcUIImage replacement:replacementString];
                [imageRanges addObject:foundImage];
                i++;
            }
    
    步骤3:

      -(void)insertImages{
    
        if ([imageRanges count]) {
            [self setScrollEnabled:NO]; //seems buggy with scrolling on
            int i = 0; //used to track the array placement for tag
    
            for(imagePlacement *myImagePlacement in imageRanges){
    
                // creates a text attachment with an image
    
                NSMutableAttributedString *placeholderAttString = [[NSMutableAttributedString alloc]initWithAttributedString:self.attributedText];
    
                NSTextAttachment *attachment = [[NSTextAttachment alloc] init];
    
                //scales image down to ration of width of view - you probably don't need this
                CGSize scaleToView = imagePlacement.imgSrc.size;
                scaleToView.width = self.frame.size.width;
                scaleToView.height = (self.frame.size.width/imagePlacement.imgSrc.size.width)*imagePlacement.imgSrc.size.height;
    
    
                attachment.image = [self imageWithColor:[UIColor clearColor] andSize:scaleToView];
                NSMutableAttributedString *imageAttrString = [[NSAttributedString attributedStringWithAttachment:attachment] mutableCopy];
    
                [self setAttributedText:placeholderAttString];
    
                i++;
    
            }
        }
        [self setScrollEnabled:YES];
    
    }
    
    
    - (UIImage *)imageWithColor:(UIColor *)color andSize:(CGSize) size {
        CGRect rect = CGRectMake(0.0f, 0.0f, size.width, size.height);
        UIGraphicsBeginImageContext(rect.size);
        CGContextRef context = UIGraphicsGetCurrentContext();
    
        CGContextSetFillColorWithColor(context, [color CGColor]);
        CGContextFillRect(context, rect);
    
        UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();
    
        return image;
    }