Анимированный UIImage в UITextView с TextKit

У меня есть UIImage, который содержит несколько кадров изображения и продолжительность, которые были нарезаны вместе из анимированного файла GIF. Если я загружу изображение в UIWebView, оно будет анимировано, как и ожидалось, но вместо этого я хочу использовать UITextView. Очевидным выбором является использование TextKit с пользовательским атрибутом NSLayoutManger и многими пользовательскими атрибутами NSAttributedString для достижения различных эффектов рисования. У меня есть один UITextView, которому я хотел бы дать NSAttributedString, содержащий NSTextAttachment для всех изображений, которые мне нужно отображать в строке. Он работает нормально, за исключением того, что когда я загружаю один из этих анимированных UIImages, они не анимируются через свои кадры. Любые мысли о том, как это сделать? Я придумал теоретический вариант:

  1. Для каждого анимированного изображения добавьте настраиваемый атрибут
  2. Когда менеджер компоновки переходит к рисованию фона, повторите этот атрибут, чтобы найти позиции вложения.
  3. Обратный вызов текстового представления для создания UIImageViews с анимированным изображением, добавления в качестве подвида и вызова startAnimating

Мне еще предстоит попробовать это, но это довольно взломано. Мне интересно, есть ли лучший вариант.

Подводя итог: я хочу анимировать UIImage внутри UITextView через NSTextAttachment внутри NSAttributedString без необходимости в дополнительных объектах UIImageView. Вы можете игнорировать тот факт, что ранее это делалось с UIWebView. UIImage имеет свойства (images, duration) для настройки анимированных кадров, которые я сейчас настроил. Если я назначу его UIImageView, он анимируется, если я установлю его как NSTextAttachment, анимации не будет.

Буду признателен за любые отзывы. Спасибо!


person afrederick    schedule 29.04.2015    source источник
comment
То же самое сегодня утром.   -  person yellottyellott    schedule 29.04.2015
comment
Можете ли вы предоставить скриншот того, как он выглядит в WebView, который вы пытаетесь воспроизвести с помощью UIImage и UITextView. Это поможет визуализировать его лучше и поможет с ответами.   -  person pteofil    schedule 04.05.2015
comment
@pteofil Я не могу сделать снимок экрана, потому что вы не будете знать, что изображение анимировано, оно будет выглядеть как статичное изображение. Чтобы уточнить: я хочу анимировать UIImage внутри UITextView через NSTextAttachment внутри NSAttributedString без необходимости в дополнительных объектах UIImageView. Вы можете игнорировать тот факт, что ранее это делалось с помощью UIWebView. UIImage имеет свойства (изображения, продолжительность) для настройки анимированных кадров, которые я сейчас настроил. Если я назначу его UIImageView, он анимируется, если я установлю его как NSTextAttachment, анимации не будет.   -  person afrederick    schedule 04.05.2015
comment
Теперь я понимаю намного лучше. Но комментарий, который вы сделали для уточнения, был бы гораздо лучше интегрирован в вопрос, где каждый мог бы его легко увидеть.   -  person pteofil    schedule 04.05.2015
comment
Если вы сохраните ссылки на объект NSTextAttachment и вручную измените свойство image после задержки, заметите ли вы какие-нибудь изменения? Если это так, вы можете создать подкласс NSTextAttachment и воссоздать поведение анимации.   -  person Robert    schedule 08.05.2015
comment
@Robert Да, это вариант, который я рассматривал, подкласс NSTextAttachment с CADisplayLink, который будет анализировать анимированный UIImage и определять, когда необходимо обновить свойство изображения текстового вложения. Это кажется лишь немного менее хакерским, чем добавление UIImageView подвидов к текстовому представлению. Я попробую, хотя и увидеть осуществимость.   -  person afrederick    schedule 11.05.2015
comment
@afrederick, как ты решил эту проблему? Я ищу точно такой же. Добавьте GIF как NSTextAttachment к UITextView, и он останется только статичным, как обычное изображение.   -  person Ivan Cantarino    schedule 20.03.2018
comment
@IvanCantarino Да, сейчас это невозможно. Я спросил инженера Apple на WWDC, и они подтвердили, что CATiledLayer, который поддерживает UITextView, не будет анимироваться. Решение состоит в том, чтобы использовать текстовое вложение в качестве заполнителя с фреймом, но без изображения, а затем добавить подпредставление поверх текстового представления с вашим анимированным изображением в том же кадре.   -  person afrederick    schedule 18.05.2018


Ответы (1)


Я думаю, что такое поведение связано с тем, что UITextView не отображает вложения с использованием подвидов UIImageView. Когда я наблюдаю иерархию представлений с NSTextAttachment, добавленными к UITextView, и без них, я не вижу никаких новых представлений (вы можете наблюдать за иерархией представлений, используя отладку представлений в Xcode или говоря [[[UIApplication sharedApplication] keyWindow] recursiveDescription]). Предположительно, UITextView просто рисует свои вложения напрямую.

Тем не менее, один из способов, который я могу придумать для включения анимируемого вложения, - это создать анимированный UIImageView самостоятельно в качестве подпредставления UITextView, разместить его точно там, где NSLayoutManager помещает NSTextAttachment, и прокручивать его всякий раз, когда прокручивается UITextView. Вы можете получить прямоугольник NSTextAttachment из NSLayoutManager, вызвав boundingRectForGlyphRange:inTextContainer: (возможно, в layoutManager:didCompleteLayoutForTextContainer:atEnd:).

person roop    schedule 07.05.2015
comment
Да, это теоретический вариант, о котором я говорил в своем вопросе. Это довольно хакерский подход, и я хотел бы избежать этого подхода, если это возможно, поскольку он будет хрупким и потребует тонны дополнительного управления этими UIImageView подвидами. UITextView, который я использую, содержится внутри UICollectionViewCell, поэтому ячейке придется управлять своими позициями и жизненным циклом. При первоначальном исследовании я сделал то, что вы сказали: я проверил подвиды текстового представления в надежде, что в нем есть вложенные представления изображений, которые я мог бы анимировать, но подвидов нет, весь рендеринг выполняется в CATiledLayer. - person afrederick; 07.05.2015
comment
Если текстовое представление находится в представлении коллекции, вам придется управлять позициями и жизненными циклами представлений изображений так же, как и для текстового представления. Вы можете создавать подпредставления UIImageView всякий раз, когда вы создаете UITextView, и размещать их в didCompleteLayout. Если текстовое представление находится в представлении коллекции, я предполагаю, что вы не используете функции прокрутки текстового представления - если это так, вам не нужно беспокоиться о прокрутке представления изображения. - person roop; 08.05.2015