Низкая производительность при анимации преобразования большого UIImageView

Я создаю последовательность заголовков для нашей игры, где каждый заголовок представляет собой изображение сетчатки размером примерно с половину экрана, которое я показываю с помощью UIImageView.

Последовательность заголовков состоит из трех простых стадий, поскольку она постепенно увеличивается и исчезает:

// 1. Fade in and grow
[UIView animateWithDuration:1.0f animations:^{
    titleImageView.alpha = 1.0f;
    titleImageView.transform = CGAffineTransformMakeScale(1.0f, 1.0f);
} completion:^(BOOL finished) {

    // 2. Stay opaque, grow a little more
    [UIView animateWithDuration:2.0f animations:^{
        titleImageView.transform = CGAffineTransformMakeScale(1.1f, 1.1f);
    } completion:^(BOOL finished) {

        // 3. Fade out, grow even further
        [UIView animateWithDuration:2.0f animations:^{
            titleImageView.alpha = 0.0f;
            titleImageView.transform = CGAffineTransformMakeScale(1.3f, 1.3f);
        } completion:nil];

    }];

}];

В начале каждого этапа анимации происходит заикание, когда пропускается один или два кадра. Это особенно заметно на старом оборудовании, таком как iPhone 4 и iPad 3, но заметно даже на iPad Air, что удивительно.

Некоторые вычеты:

  • Это не имеет ничего общего с загрузкой самого UIImage, потому что я пытался предварительно загрузить данные и убедиться, что PNG был распакован. Также заикание происходит на каждом этапе анимации, даже после того, как она какое-то время была на экране.
  • Я использовал инструмент Time Profiler и заметил, что CA, казалось, копировал данные PNG в фоновом режиме каждый раз, когда он заикался, хотя я не уверен, почему / для чего. Конечно, CALayers не должны заново создавать какие-либо данные изображения на ЦП каждый раз, когда изменяется transform?
  • РЕДАКТИРОВАТЬ. Также обратите внимание, что я пробовал без анимации (просто устанавливая эти свойства преобразования, также без альфа-изменений) и получил те же результаты.

Также обратите внимание, что у меня в фоновом режиме работает некоторая графика OpenGL ES (это игра с элементами управления UIKit на переднем плане), но в прошлом это не вызывало проблем...


person Joseph Humfrey    schedule 02.06.2014    source источник
comment
UIImageView отвечает за собственный дочерний слой, который содержит фактическое изображение. Возможно, когда вы устанавливаете преобразование, оно пытается перерендериться, чтобы лучше выглядеть в новом масштабе.   -  person Brian Nickel♦    schedule 02.06.2014
comment
Да, это звучит как довольно разумное объяснение. Хотя не знаю, что с этим делать!   -  person Joseph Humfrey    schedule 02.06.2014
comment
Используйте инструмент Core Animation, как описано здесь: разработчик. apple.com/library/ios/documentation/DeveloperTools/   -  person matt    schedule 02.06.2014


Ответы (1)


Итак, это немного некрасиво, но я решил это двумя подходами одновременно:

  1. Я преобразовал каскадные анимации UIView в единую анимацию с ключевыми кадрами CALayer, чтобы они были непрерывными. вместо того, чтобы останавливаться на каждом этапе, вызывать обработчик завершения и запускать новую анимацию. Возможно, это останавливает их от «установки» и повторного рендеринга в новом масштабе, как указал Брайан Никель.
  2. Но это не предотвратило самого первого заикания, поскольку оно показывало каждый новый UIImage. Чтобы решить эту проблему, я создал все UIImageViews (всего их 6) заранее, добавил их в суперпредставление и установил их альфу на ноль. Изображения не огромные, и их не слишком много, так что это казалось нормальным.
person Joseph Humfrey    schedule 02.06.2014
comment
спасибо Джозеф. Ваш второй трюк, добавление его в вид и затем изменение прозрачности, — это гениальный маленький трюк, чтобы остановить заикание при перерисовке! - person Confused; 23.09.2014