iOS CAKeyframeAnimation rotationMode on UIImageView

Я экспериментирую с покадровой анимацией положения объекта UIImageView, движущегося по траектории безье. На этом рисунке показано начальное состояние перед анимацией. Синяя линия - это путь - изначально движущийся прямо вверх, светло-зеленая рамка - это начальная ограничительная рамка или изображение, а темно-зеленый "призрак" - это изображение, которое я двигаю:

Initial state

Когда я запускаю анимацию с rotationMode, установленным на nil, изображение сохраняет ту же ориентацию на протяжении всего пути, как и ожидалось.

Но когда я запускаю анимацию с rotationMode, установленным на kCAAnimationRotateAuto, изображение немедленно поворачивается на 90 градусов против часовой стрелки и сохраняет эту ориентацию на протяжении всего пути. Когда оно достигает конца пути, оно перерисовывается в правильной ориентации (на самом деле оно показывает UIImageView, который я перепозиционировал в конечное место)

enter image description here

Я наивно ожидал, что rotationMode будет ориентировать изображение по касательной к пути, а не по нормали, особенно когда в документации Apple для CAKeyframeAnimation rotationMode указано

Определяет, вращаются ли объекты, анимированные вдоль пути, в соответствии с касательной к пути.

Так каково же здесь решение? Должен ли я предварительно повернуть изображение на 90 градусов по часовой стрелке? Или я что-то упускаю?

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


Edit 2nd March

Я добавил шаг вращения перед анимацией пути, используя аффинное вращение, как:

theImage.transform = CGAffineTransformRotate(theImage.transform,90.0*M_PI/180);

и затем после анимации пути, сбрасывая вращение:

theImage.transform = CGAffineTransformIdentity;

Это заставляет изображение следовать по пути ожидаемым образом. Однако теперь я столкнулся с другой проблемой - изображение мерцает. Я уже ищу решение проблемы мерцания в этом вопросе SO:

iOS CAKeyFrameAnimation масштабирование мерцает в конце анимации

Так что теперь я не знаю, сделал ли я все лучше или хуже!


Редактировать 12 марта

Хотя Калеб указал, что да, я должен предварительно повернуть мое изображение, Роб предоставил потрясающий пакет кода, который почти полностью решил мои проблемы. Единственное, что Роб не сделал, это компенсацию того, что мои активы были нарисованы с вертикальной, а не горизонтальной ориентацией, таким образом, все еще требуя предварительного поворота на 90 градусов перед выполнением анимации. Но справедливо, что я должен сделать часть работы, чтобы все заработало.

Итак, мои небольшие изменения в решении Роба для удовлетворения моих требований таковы:

  1. Когда я добавляю UIView, я предварительно поворачиваю его, чтобы противостоять внутреннему вращению, добавленному путем установки rotationMode:

    theImage.transform = CGAffineTransformMakeRotation(90*M_PI/180. 0);

  2. Мне нужно сохранить это вращение в конце анимации, поэтому вместо того, чтобы просто взорвать преобразование вида новым масштабным коэффициентом после определения блока завершения, я строю масштаб на основе текущего преобразования:

    theImage.transform = CGAffineTransformScale(theImage.transform, scaleFactor, scaleFactor);

И это все, что мне нужно было сделать, чтобы заставить мое изображение следовать по пути, как я ожидал!


Редактировать 22 марта

Я только что загрузил на GitHub демонстрационный проект, который демонстрирует перемещение объекта по траектории безье. Код можно найти по адресу PathMove

Я также написал об этом в своем блоге по адресу Перемещение объектов по безье-пути в iOS

11
задан Community 23 May 2017 в 11:48
поделиться