Анимация CGAffineTransform в iOS8 выглядит иначе, чем в iOS7
Я пытаюсь найти причину, по которой анимация свойства UIView
transform выглядит иначе в iOS 8, чем iOS 6/7.
Для простого примера, до iOS 8:
myView.transform = CGAffineTransformRotate(CGAffineTransformIdentity, 1.57);
[UIView animateWithDuration:5 animations:^{
myView.transform = CGAffineTransformTranslate(plane.transform, 100, 0);
}];
дает ожидаемый результат, "myView" поворачивается на 90 градусов и перемещается вниз, но в iOS8 при анимации перевода он начинается с того момента, когда я не мог найти объяснения (что нарушает анимацию).
Кто-нибудь знает объяснение? Спасибо заранее!
Ответы
Ответ 1
CGAffineTransformIdentity ведет себя по-разному на ios7 и ios8. Это связано с классами автоматической компоновки и размера. Решение заключается в удалении ограничений, которые конфликтуют с анимацией на ios7.
// solve the constraint-animation problem
if(NSFoundationVersionNumber <= NSFoundationVersionNumber_iOS_7_1) {
// iOS7 remove constraints that conflict with animation
if (self.centerYAlignment != nil) {
self.view.removeConstraint(self.centerYAlignment) //is an IBOutlet
}
} else {
// iOS8 constraint animations are fine
}
Ответ 2
Я думаю, что причиной является только ошибка iOS8, но вместо этого я использую CAAnimation, и она работает как ожидается на iOS8.
Ответ 3
У меня были проблемы с резким преобразованием вращения в iOS7. Решила это, вставив мой повернутый вид внутри контейнера и центрируя повернутое изображение внутри.
Ответ 4
У меня также возникает проблема с масштабированием. Я думаю, это может быть одинаково с поворотом. Не могли бы вы попробовать это?
myView.transform = CGAffineTransformConcat(myView.transform , CGAffineTransformMakeRotate(1.57));
[UIView animateWithDuration:5 animations:^{
myView.transform = CGAffineTransformTranslate(plane.transform, 100, 0);
}];
Возможно, также необходимо использовать CGAffineTransformMakeTranslate и CGAffineTransformConcat, что тоже не я.
Самое худшее в этом: вам нужно будет делать if/else в версиях iOS, потому что это выглядело бы странно на iOS 7. Надеюсь, что это исправлено Apple до или с выпуском iOS 8.
Ответ 5
Я согласен с Pbk в том, что он связан с классами размера в io8. uiviewcontrollers должны быть изменены с помощью uitraitcollections в зависимости от ориентации устройства. В противном случае вы получаете диспетчер uiviewcontroller в портретном режиме, в то время как телефон находится в ландшафтном режиме, когда вы пытаетесь его повернуть. Итак, правильные шаги - повернуть и переопределить uitraitcollections
Ответ 6
Это не совсем связано, но я боролся с тем, что CGAffineTransformScale
вообще не работает на iOS7 в довольно сложной анимации. Оказывается, моя проблема заключалась в том, что iOS7 не может вычислять CGAffineTransformScale
с помощью CGAffineTransformRotate
одновременно. В iOS7 последний анимационный вызов, который вы делаете, является единственным, который анимируется, поэтому происходит только ротация. Эта ошибка исправлена в iOS8.
Мое решение - упростить мою анимацию для iOS7, только включив причудливые вещи в iOS8:
//Pre-animation setup:
CGFloat radians = (M_PI/180) * (-15); //Get a human-readable number in degrees
self.badgeImage.alpha = 0; //Start the image as invisible
self.badgeImage.transform = CGAffineTransformScale(self.badgeImage.transform, 1.5, 1.5); //Start the image as scaled bigger than normal
if(NSFoundationVersionNumber > NSFoundationVersionNumber_iOS_7_1) { //See below. We will not be rotating the image in iOS7
self.badgeImage.transform = CGAffineTransformRotate(self.badgeImage.transform, radians); //Rotate the image if iOS8
}
//Animation Pieces:
//Fade in
[UIView animateWithDuration: 0.5
delay:0
options:0
animations:^{
self.badgeImage.alpha = 1.0f; //Return image to opaque
}
completion:NULL];
//Scale with bounce
[UIView animateWithDuration: 1.1
delay:0
usingSpringWithDamping:0.3 //Not as good as Android bounce interpolator, but I'll take it
initialSpringVelocity:-1.0f //A negative velocity here makes the animation appear more like gravity than spring
options:0
animations:^{
self.badgeImage.transform = CGAffineTransformScale(self.badgeImage.transform, 0.67, 0.67); //Return image to its original size. These arguments are relative to its current scale.
}
completion:NULL];
//Rotation
if(NSFoundationVersionNumber > NSFoundationVersionNumber_iOS_7_1) { //This second animation call negates the first one on iOS7, so remove it.
[UIView animateWithDuration: 0.9
delay:0
options:UIViewAnimationOptionCurveEaseOut
animations:^{
self.badgeImage.transform = CGAffineTransformRotate(self.badgeImage.transform, (radians * -1)); //Rotate the image back to its original orientation if iOS8
}
completion:NULL];
}
Конечно, вы все же можете объединить несколько эффектов в iOS7, если вы используете функцию t24 > с запутанным именем. Например, в настройке предварительной анимации вы можете установить как поворот, так и масштаб, затем установить для вызова CGAffineTransformMakeScale(1,1)
в reset изображение в его исходные показатели (MakeScale
аргументы являются конкретными, а не относительными - еще более запутанными!). Это не всегда предпочтительнее, например, мой пример выше, где "подпрыгивание" анимации также отскакивает от поворота.