2015-08-13 4 views
0

У меня есть 5 последовательных UILabel так:Анимационные несколько последовательных UILabels с той же скоростью, в то же время к той же точке

enter image description here

Они были созданы с той же рамке, чем этикетки 1, а затем были перемещается с использованием свойства CGAffineTransform. Таким образом, CGAffineTransformIdentity вернет их всех поверх метки 1.

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

До сих пор я сделал как следующий, но он не работает:

var reversedLabels = getLabels().reverse() 
let duration: NSTimeInterval = 5 
UIView.animateWithDuration(duration, animations: { 
    for (index, label) in enumerate(reversedLabels) { 
     let relativeDuration: NSTimeInterval = duration * Double(index)/Double(reversedLabels.count) 

     UIView.animateWithDuration(relativeDuration, animations: { 
      label.transform = CGAffineTransformIdentity 
      }, completion: { finished in 
       label.hidden = true 
     }) 
    } 
    }, completion: { finished in 
     for (index, label) in enumerate(reversedLabels) { 
      label.removeFromSuperview() 
     } 
}) 

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

Как вы это сделаете? (и почему «окончательное» завершение не вызывается в самом конце?)

ответ

1

Поскольку вы не анимируете какое-либо анимационное свойство любого вида внутри первого блока анимации, блок завершения будет выполнен сразу после начала анимации. Я не могу понять, почему вам нужен этот блок вообще. В завершении внутренней анимации вы скрываете ваши ярлыки, что то же самое поведение UI, как удаление их из надтаблицы, так что, возможно, этот блок коды (без внешней анимации) может принести вам желаемый результат

for (index, label) in enumerate(reversedLabels) { 

    let relativeDuration: NSTimeInterval = duration * Double(index)/Double(reversedLabels.count) 

    UIView.animateWithDuration(relativeDuration, delay: 0.0, options: UIViewAnimationOptions.CurveLinear, animations: { 

      label.transform = CGAffineTransformIdentity 

      }, completion: {finished in 
      label.removeFromSuperview()= 
     }) 
} 

Редакция: relativeDuration следует вычислять, добавляя +1 к индексу, иначе первая анимация будет иметь продолжительность 0. Также для достижения такой же скорости для всех анимаций вы должны использовать UIViewAnimationOptions.CurveLinear

+0

ok Я понимаю, почему он пошел прямо в блок завершения. Проблема с выполнением этого только с внутренним блоком состоит в том, что все они начинаются вместе (что хорошо), но все они идут в одно и то же место (что хорошо) за такое же время, поэтому с разной скоростью. – Nico

+0

Я до сих пор не совсем понимаю ваши требования. Вы хотите сначала запустить анимационную метку 5 и после того, как метка 5 находится поверх метки 4, начните анимационную метку 4 в начало метки 3? –

+0

Нет, я хочу начать все вместе и закончить каждый из них, когда они находятся поверх метки 1. Но я хочу, чтобы они имели одинаковую скорость, например, если 5 последовало за 4, что было следующим 3 и так далее. Но с этим блоком, поскольку продолжительность такая же, но расстояния разные, 5 будет быстрее, чем 4, которые будут идти быстрее, чем 3 и так далее. – Nico

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