цель c: CGAffineTransformMakeRotation

У меня есть изображение, которое я хочу мотать туда-сюда (один раз) вокруг фиксированной точки. Итак, у меня есть следующий код:

[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:1.5];
myDial.transform = CGAffineTransformMakeRotation(degreesToRadians(45)); //lineA
[UIView commitAnimations];

[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:1.5];
myDial.transform = CGAffineTransformMakeRotation(degreesToRadians(0 )); //lineB
[UIView commitAnimations];

Что происходит, когда я запускаю приведенный выше код, так это то, что строка A выполняется немедленно (а не через 1,5 секунды). Сразу после этого строка B выполняется за 1,5 секунды. Я хочу, чтобы обе анимации занимали 1,5 секунды каждая. Как я могу это сделать


person pnizzle    schedule 30.05.2012    source источник
comment
Похоже, вы перепутали продолжительность анимации и задержку анимации.   -  person Otium    schedule 30.05.2012


Ответы (3)


Вместо того, чтобы пытаться объединить две анимации UIView для создания одной визуальной анимации, вы можете просто использовать Core Animation и сделать все это в одной анимации. Используя Core Animation, вы можете заставить анимацию автоматически переворачиваться (переходить на 45 градусов в течение 1,5 секунд, а затем обратно в течение той же продолжительности), и вам не придется заботиться о синхронизации двух анимаций вместе. Вы можете сделать это следующим образом:

CABasicAnimation *rotate = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"];
[rotate setFromValue:[NSNumber numberWithFloat:0.0]];
[rotate setToValue:[NSNumber numberWithFloat:degreesToRadians(45)]];
[rotate setDuration:1.5];
[rotate setAutoreverses:YES]; // go back the same way
[rotate setTimingFunction:[CAMediaTimingFunction functionWithName: kCAMediaTimingFunctionEaseInEaseOut]];

[[myDial layer] addAnimation:rotate forKey:@"dangleMyDial"];

Если вы не импортировали QuartzCore.framework в свой проект и импортировали файл , вам потребуется сделать это, чтобы базовая анимация заработала.

person David Rönnqvist    schedule 30.05.2012
comment
Я разместил следующее: [self PerformSelector:@selector(reverseRotate) withObject:nil afterDelay:0.5]; после первой анимации, где метод reverseRotate содержит вторую анимацию. Он отлично работает. Я проверил ваш код, и он также отлично работает. Лучше, чем создавать отдельный метод для второй анимации - person pnizzle; 30.05.2012

Идея состоит в том, чтобы выполнить следующую последовательность анимации в функции завершения.

Я протестировал этот код. Я беру на себя смелость немного изменить номер, чтобы он больше походил на телефонный номер.

[UIView animateWithDuration: 1.0 delay: 0 options: UIViewAnimationOptionCurveLinear animations:^{
    myDial.transform = CGAffineTransformRotate(rect.transform, M_PI / 4); 
} completion:^(BOOL finished) {
    [UIView animateWithDuration: 0.7 delay: 0 options: UIViewAnimationOptionCurveEaseIn animations:^{
        myDial.transform = CGAffineTransformIdentity;
    } completion: nil];
}];
person nhahtdh    schedule 30.05.2012
comment
Ммм, как бы я использовал анимациюDelay с моим кодом. Мне нужно, чтобы первая анимация завершилась за 1,5 секунды, а затем вторая анимация последовала сразу за ней и также заняла 1,5 секунды. - person pnizzle; 30.05.2012
comment
да я пробовал так делать. Анимация 1 по-прежнему происходит немедленно (во вспышке), а анимация 2 спустя 1,5 секунды выполняется (при необходимости требуется 1,5 секунды для завершения). - person pnizzle; 30.05.2012
comment
@nhahtdh Когда вы говорите, что это действительно не работает, вы устанавливаете задержку как [UIView setAnimationDelay:2.0]; или помните, что вам нужно установить задержку с текущего времени? Вот так: [UIView setAnimationDelay:CACurrentMediaTime() + 2.0]; - person David Rönnqvist; 30.05.2012
comment
@DavidRönnqvist: Просто для ясности: метод, который не работает, основан на коде OP. Я использую первый в вашем комментарии, чтобы установить задержку анимации на вторую анимацию. - person nhahtdh; 31.05.2012

Если я правильно понимаю, о чем вы спрашиваете, я думаю, что вижу вашу проблему. setAnimationDuration не задерживает начало анимации; скорее, он сообщает анимации, как долго она должна быть завершена. Если вы на самом деле пытаетесь отложить начало анимации, рассмотрите возможность использования NSTimer для этого. (Или с помощью метода setAnimationDelay). Настройте NSTimer, который запускает первую "ротацию", ждет, пока она не будет завершена, а затем запускает вторую, либо вызывая другую NSTimer, либо используя цикл.

person Radrider33    schedule 30.05.2012
comment
У меня есть циферблат, и я хочу, чтобы он повернулся на 45 градусов за 1,5 секунды. Сразу после этого я хочу, чтобы он вернулся в исходное положение (0 градусов) через 1,5 секунды. Но с кодом, который я написал, вторая анимация не ждет завершения первой. Вместо этого первая анимация происходит немедленно, а вторая затем занимает 1,5 секунды от положения 45 градусов до возврата обратно в 0 градусов. - person pnizzle; 30.05.2012
comment
Вы можете попробовать использовать как setAnimationDelay, так и NSTimer. Настройте первую анимацию для немедленного запуска, а затем используйте либо таймер, либо задержку анимации, чтобы отложить вторую анимацию до 1,5 с. Таким образом, он повернется до 45 за 1,5 с, а затем вторая анимация запустится, как только она будет завершена. Если один способ не работает, попробуйте другой. - person Radrider33; 30.05.2012