2013-05-28 1 views
1

У меня есть несколько изображений, на которых я запускаю непрерывную анимацию. Как можно обновить эти запущенные анимации плавно, чтобы между ними не было видимого перехода, если только часть анимации.Обновление плавных анимаций плавно

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

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

Мне нужно, чтобы оно было бесшовным. например этот блок кода не вызывает плавное масштабирование, даже если он использует UIViewAnimationOptionBeginFromCurrentState

[UIView animateWithDuration:0.5 
         delay:0 
        options:UIViewAnimationOptionBeginFromCurrentState | UIViewAnimationOptionCurveEaseOut //| UIViewAnimationOptionRepeat 
       animations:(void (^)(void)) ^{ 
        imageViewToScale.transform = CGAffineTransformMakeScale(1.2, 1.2); 
       } 
       completion:^(BOOL finished){ 
        //imageViewToScale.transform=CGAffineTransformIdentity; 
       }]; 

ответ

2

Чтобы быть честным, если ваш будет иметь непрерывные анимации на ваших представлений, которые будут изменяющие там говорится, во время выполнения UIView анимации не он лучший подход и может вызвать джиттер, в то время как обработчик завершения вызывается снова и снова и т. д.

Однако, вы хотите сделать 2 анимации в блоке, вы можете установить масштаб и вращение в одном блоке, и они будут выполняться одновременно. Или вы можете вызвать функцию, которая запускает блок, и по завершении вызывает его снова, чтобы увидеть, есть ли какие-либо новые анимации для этого представления. Когда их нет, блок завершения просто останавливается, что-то вроде рекурсивного использования, хотя это не тот подход, который я бы не рекомендовал, если вы многого времени выполняете на многих представлениях.

В OpenGLES вы используете NSTimer для запуска непрерывной анимации, которая будет обрабатывать обновление всех анимаций в вашем приложении. Если вы идете по этому маршруту, это намного сложнее, и вам нужно реализовать функции ослабления/квадратичной кривой для гладкой анимации. Однако, если вы расширяете кланы, вы можете устанавливать состояния для каждого изображения, а затем, когда срабатывает таймер, вы можете обновить его преобразование на основе тех состояний, которые вы ему дали. Поэтому, когда он вращает определенное количество градусов/радианов, вы можете установить его на масштаб. Теперь, чтобы сохранить анимацию плавно, вам нужно будет использовать NSTimerIntervals, чтобы убедиться, что вы умножаете расстояние, перемещенное по времени, прошедшее с целью получения плавной анимации. Лично это маршрут, который я использую для вещей, которые могут постоянно перемещаться по экрану, но могут быть убиты, если вам нужно только перемещать вещи дважды, а затем делать.

EDIT: Код для выполнения второго шага, как вы просили!

Итак, вам нужно объявить NSTimer, который проведет опрос ваших шагов анимации и NSTimeInterval, чтобы вы обновили анимацию каждый шаг только на количество пройденного времени.

NSTimer *animationTimer; 
NSTimeInterval animationInterval; 
NSTimeInterval lastUpdateTime; 
float currentRotation; 
float current scale; 

В-третьих вам нужно настроить NSTimer чтобы выпалить обновление ваших просмотров:

- (void)startAnimation 
{ 
    animationTimer = [NSTimer scheduledTimerWithTimeInterval:animationInterval target:self selector:@selector(drawView:) userInfo:nil repeats:YES]; 
} 

- (void)stopAnimation 
{  
    [animationTimer invalidate]; 
    animationTimer = nil; 
} 

Затем вам нужно пнуть штуку, когда ваш вид начинается или когда вы хотите, чтобы начать anmation что-то как это работает

- (void)setAnimationInterval:(NSTimeInterval)interval 
{ 
    animationInterval = interval; 

    if(animationTimer) 
    { 
     [self stopAnimation]; 
     [self startAnimation]; 
    } 
} 

Затем в drawView: Метод вам необходимо обновить преобразования в зависимости от времени, прошедшего между каждым огнем таймера так, что анимация гладкая и с течением времени. По существу линейное преобразование в этой точке.

- (void)drawView:(id)sender 
{ 
    if(lastUpdateTime == -1) 
    { 
     lastUpdateTime = [NSDate timeIntervalSinceReferenceDate]; 
    } 

    NSTimeInterval timeSinceLastUpdate = [NSDate timeIntervalSinceReferenceDate] - lastUpdateTime; 

    currentRotation = someArbitrarySCALEValue * timeSinceLastUpdate; 
    currentScale = someArbitraryROTATIONValue * timeSinceLastUpdate; 

    CGAffineTransform scaleTrans = CGAffineTransformMakeScale(currentScale,currentScale); 
    CGAffineTransform rotateTrans = CGAffineTransformMakeRotation(currentRotation * M_PI/180); 

    imageViewToScale.transform = CGAffineTransformConcat(scaleTrans, rotateTrans); 


    lastUpdateTime = [NSDate timeIntervalSinceReferenceDate]; 
} 

Примечание это не добавит ослабление к анимации и не будет в физике до остановки вам нужно будет играть с этим. Также вам может потребоваться убедиться, что, когда вращение переместится через 360, вы сбросите его на 0 и преобразуете между градусами и радианами соответственно.

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

Посмотрите на квадратичные графики, чтобы облегчить плавное движение вещей во времени, по существу, квадратичную интерполяцию.

+0

Мне нужно запустить единую постоянную анимацию, вращение. В зависимости от некоторых данных мне нужно обновить анимацию, например. изменить скорость вращения или масштабировать изображение. – jarryd

+0

Тогда я полностью пройду маршрут, используя таймер, и используя NSTimeIntervals, чтобы обновить анимацию «на лету». Я отправлю пример кода выше, что вам нужно сделать 1 секунда – Dev2rights

+0

Спасибо. Посмотрите, когда вы разместите его. :) – jarryd

 Смежные вопросы

  • Нет связанных вопросов^_^