CGAffineTransform scale и перевод - прыжок перед анимацией
Я борюсь с проблемой, касающейся шкалы CGAffineTransform и перевода, где, когда я устанавливаю преобразование в блоке анимации в представлении, которое уже имеет преобразование, перед тем, как оживить, перескакивает бит.
Пример:
// somewhere in view did load or during initialization
var view = UIView()
view.frame = CGRectMake(0,0,100,100)
var scale = CGAffineTransformMakeScale(0.8,0.8)
var translation = CGAffineTransformMakeTranslation(100,100)
var concat = CGAffineTransformConcat(translation, scale)
view.transform = transform
// called sometime later
func buttonPressed() {
var secondScale = CGAffineTransformMakeScale(0.6,0.6)
var secondTranslation = CGAffineTransformMakeTranslation(150,300)
var secondConcat = CGAffineTransformConcat(secondTranslation, secondScale)
UIView.animateWithDuration(0.5, animations: { () -> Void in
view.transform = secondConcat
})
}
Теперь, когда buttonPressed() называется просмотром, перед тем, как начать анимацию, переходите в левый верхний угол около 10 пикселей. Я только видел эту проблему с преобразованием concat, используя только трансляцию трансляции. Прекрасно.
Изменить: Поскольку я провел много исследований по этому вопросу, я думаю, что я должен упомянуть, что эта проблема появляется независимо от того, включена ли автоматическая компоновка
Ответы
Ответ 1
Я столкнулся с той же проблемой, но не смог найти точный источник проблемы. Кажется, что прыжок появляется только в очень специфических условиях: если представление анимируется из преобразования t1
в преобразование t2
, и оба преобразования представляют собой комбинацию масштаба и перевода (это именно ваш случай). Учитывая следующее обходное решение, которое для меня не имеет смысла, я предполагаю, что это ошибка в Core Animation.
Сначала я попытался использовать CATransform3D
вместо CGAffineTransform
.
Старый код:
var transform = CGAffineTransformIdentity
transform = CGAffineTransformScale(transform, 1.1, 1.1)
transform = CGAffineTransformTranslate(transform, 10, 10)
view.layer.setAffineTransform(transform)
Новый код:
var transform = CATransform3DIdentity
transform = CATransform3DScale(transform, 1.1, 1.1, 1.0)
transform = CATransform3DTranslate(transform, 10, 10, 0)
view.layer.transform = transform
Новый код должен быть эквивалентен старому (четвертый параметр установлен на 1.0
или 0
, так что в направлении z
нет масштабирования/перевода), и на самом деле он показывает тот же прыжок, Однако здесь идет черная магия: в преобразовании шкалы измените параметр z
на что-либо, отличное от 1.0
, например:
transform = CATransform3DScale(transform, 1.1, 1.1, 1.01)
Этот параметр не должен иметь никакого эффекта, но теперь переход исчез.
🎩✨
Ответ 2
Источником проблемы является отсутствие перспективной информации для преобразования.
Вы можете добавить перспективную информацию, изменяющую свойство m34
вашего 3D-преобразования
var transform = CATransform3DIdentity
transform.m34 = 1.0 / 200 //your own perspective value here
transform = CATransform3DScale(transform, 1.1, 1.1, 1.0)
transform = CATransform3DTranslate(transform, 10, 10, 0)
view.layer.transform = transform
Ответ 3
Похоже, что внутренняя ошибка анимации Apple UIView. Когда Apple интерполирует CGAffineTransform
изменения между двумя значениями для создания анимации, он должен выполнить следующие шаги:
- Извлечение трансляции, масштабирования и вращения
- Интерполяция значений извлеченных значений начинается с конца
- Соберите
CGAffineTransform
для каждого шага интерполяции
Сборка должна быть в следующем порядке:
- Перевод
- Масштабирование
- Вращение
Но похоже, что Apple делает перевод после масштабирования и вращения. Эта ошибка должна быть исправлена Apple.
Ответ 4
Вместо CGAffineTransformMakeScale() и CGAffineTransformMakeTranslation(), которые создают преобразование, основанное на CGAffineTransformIdentity (в основном без преобразования), вы хотите масштабировать и транслировать на основе текущего преобразования данных с использованием CGAffineTransformScale() и CGAffineTransformTranslate(), которые запускаются с существующим преобразованием.