Подтвердить что ты не робот

Анимация 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 при анимации перевода он начинается с того момента, когда я не мог найти объяснения (что нарушает анимацию).

Кто-нибудь знает объяснение? Спасибо заранее!

4b9b3361

Ответ 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 аргументы являются конкретными, а не относительными - еще более запутанными!). Это не всегда предпочтительнее, например, мой пример выше, где "подпрыгивание" анимации также отскакивает от поворота.