Я экспериментирую с покадровой анимацией положения объекта UIImageView, движущегося по траектории безье. На этом рисунке показано начальное состояние перед анимацией. Синяя линия - это путь - изначально движущийся прямо вверх, светло-зеленая рамка - это начальная ограничительная рамка или изображение, а темно-зеленый "призрак" - это изображение, которое я двигаю:
Когда я запускаю анимацию с rotationMode, установленным на nil
, изображение сохраняет ту же ориентацию на протяжении всего пути, как и ожидалось.
Но когда я запускаю анимацию с rotationMode, установленным на kCAAnimationRotateAuto
, изображение немедленно поворачивается на 90 градусов против часовой стрелки и сохраняет эту ориентацию на протяжении всего пути. Когда оно достигает конца пути, оно перерисовывается в правильной ориентации (на самом деле оно показывает UIImageView, который я перепозиционировал в конечное место)
Я наивно ожидал, что 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 градусов перед выполнением анимации. Но справедливо, что я должен сделать часть работы, чтобы все заработало.
Итак, мои небольшие изменения в решении Роба для удовлетворения моих требований таковы:
Когда я добавляю UIView, я предварительно поворачиваю его, чтобы противостоять внутреннему вращению, добавленному путем установки rotationMode
:
theImage.transform = CGAffineTransformMakeRotation(90*M_PI/180. 0);
Мне нужно сохранить это вращение в конце анимации, поэтому вместо того, чтобы просто взорвать преобразование вида новым масштабным коэффициентом после определения блока завершения, я строю масштаб на основе текущего преобразования:
theImage.transform = CGAffineTransformScale(theImage.transform, scaleFactor, scaleFactor);
И это все, что мне нужно было сделать, чтобы заставить мое изображение следовать по пути, как я ожидал!
Редактировать 22 марта
Я только что загрузил на GitHub демонстрационный проект, который демонстрирует перемещение объекта по траектории безье. Код можно найти по адресу PathMove
Я также написал об этом в своем блоге по адресу Перемещение объектов по безье-пути в iOS