Заменить изображение NSTextattachment на NSMutableattributedString

Я создаю UITextView с текстом и изображениями (подкласс NSTextstorage для отображения моего контента)

У меня есть текстовое содержимое с URL-адресами изображений. Итак, моя проблема в том, что мне нужно загрузить все изображения, если они не кэшированы.

Итак, я хочу сначала вставить изображение-заполнитель, загрузить изображение, а затем заменить изображение-заполнитель загруженным.

Вот как я делаю свою работу.

Во-первых, я форматирую свой текст с URL-адресом изображения, заменяя все URL-адреса этим тегом:

[IMG]url[/IMG]

Затем я использую регулярное выражение, чтобы получить все эти теги.

Я проверяю, есть ли кешированное изображение или нет. Если нет, я извлекаю все URL-адреса, загружаю их и кэширую.

Я создал класс NSObject ImageCachingManager и объявил метод делегата, вызываемый при загрузке изображения:

@protocol ImageCachingManagerDelegate <NSObject>

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

@end

Таким образом, я настаивал на том, чтобы использовать URL-адрес изображения, полученный методом делегата, для поиска соответствующего URL-адреса в моей атрибутной строке NSTextstorage и замены текущего изображения NSTextattachment загруженным.

Но я не знаю, как это сделать...

Спасибо за помощь !


person Pwyll28    schedule 20.02.2014    source источник


Ответы (1)


Сейчас я работаю над чем-то очень похожим на это и думаю, что это может помочь. Код очень альфа-версия, но, надеюсь, он поможет вам перейти к следующему шагу — я пошагово выполню:

Общий цикл 1. Найдите теги изображений в полнотекстовой части с помощью Reg Ex или XPath. Лично я считаю, что Hppl более мощный, но если ваш контент хорошо структурирован и надежен, регулярное выражение, вероятно, подойдет.

https://github.com/topfunky/hpple

  1. Уменьшите пространство этого совпадения до 1 символа и сохраните этот диапазон. TextAttachment занимает только 1 символ пространства в текстовом представлении, поэтому лучше уменьшить его до 1, в противном случае, когда вы заменяете свое первое совпадение символов в диапазоне первым текстовым приложением, следующий маркер диапазона устаревает, что приведет к проблемам. В зависимости от того, сколько обработки вам нужно для ввода этого текста во время инициализации, это важный шаг, мне нужно много обрабатывать текст, и диапазоны меняются во время этого синтаксического анализа, поэтому я создал массив специальных символов, которые я знаю никогда не будет на входе и помещать эти отдельные символы в зарезервированное пространство, в то же время я сохраняю этот специальный символ и src изображения в массиве очень простого подкласса NSObject, в котором хранится SpecialChar, ImgSrc plus имеет пространство для NSRange, но я в основном снова нахожу специальный символ позже в процессе, потому что он был перемещен с этого момента, а затем устанавливаю nsrange в самом конце обработки - это может не быть необходимым в вашем случае, но принцип таков такой же; Вам нужен пользовательский объект с NsRange (который станет текстовым вложением) и imgSource.

  2. Прокрутите этот массив, чтобы добавить заполнитель imageAttachments к вашей строке с атрибутами. Вы можете сделать это, добавив прозрачное изображение или «загружаемое» изображение. Вы также можете проверить кеш на наличие существующих изображений на этом этапе и пропустить заполнитель, если он существует в кеше.

  3. Используя вашего делегата, когда изображение успешно загружено, вам нужно заменить текущее вложение новым. Заменив заполнитель в диапазоне, который вы уже сохранили в своем объекте. Создайте заполнитель attributeString с помощью NSTextAttachment, а затем замените этот диапазон, как показано ниже.

Некоторый пример кода:

Шаги 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;
}
person jimmyjamesdub    schedule 01.03.2014