Как настроить анимационную кривую при использовании анимации ключевого кадра в ios?
Как настроить анимационную кривую при использовании анимации ключевого кадра UIView:
animateKeyframesWithDuration:delay:options:animations:completion:
Все, что я делаю в блоке анимации, кажется линейным (если я не использую параметр UIViewKeyframeAnimationOptionCalculationModeCubic
, но это не то, что я хочу).
Я хочу, чтобы в анимации, как опция UIViewAnimationOptionCurveEaseOut
, была легко вырезана кривая, используя регулярную анимацию:
animateWithDuration:delay:options:animations:completion:
Ответы
Ответ 1
Если вы используете ключевые кадры, вы должны сами определить кривую. Если вы добавляете линейные ключевые кадры, у вас есть линейная анимация. Если вы добавите нелинейные ключевые кадры, у вас будет нелинейная анимация.
frameStartTime
- ваш друг здесь... он всегда будет линейным между ключевыми кадрами (или шагами/кубиками/кубиками, как определено в UIViewKeyframeAnimationOptionCalculationMode
)
UIViewKeyframeAnimationOptionCalculationModeLinear = 0 << 9,
UIViewKeyframeAnimationOptionCalculationModeDiscrete = 1 << 9,
UIViewKeyframeAnimationOptionCalculationModePaced = 2 << 9,
UIViewKeyframeAnimationOptionCalculationModeCubic = 3 << 9,
UIViewKeyframeAnimationOptionCalculationModeCubicPaced = 4 << 9
Чтобы рассчитать правильные значения времени, вы можете использовать это как ссылку:
RBBEasingFunction
например. EaseInOutQuad
как это (где t - относительное время в анимации):
if (t < 0.5) {
return 2 * t * t;
} else {
return -1 + (4 - 2 * t) * t;
}
Ответ 2
Swift 2.0 не разрешает кастинг UIViewAnimationOptions
как UIViewKeyframeAnimationOptions
. Это также не позволит |
объединить их.
Однако для UIViewKeyframeAnimationOptions
существует инициализатор, который принимает rawValue
. Итак, следующий код работает, чтобы положить UIViewAnimationOptions
в UIViewKeyframeAnimationOptions
:
let animationOptions: UIViewAnimationOptions = .CurveEaseOut
let keyframeAnimationOptions: UIViewKeyframeAnimationOptions = UIViewKeyframeAnimationOptions(rawValue: animationOptions.rawValue)
Затем я могу пройти keyframeAnimationOptions
до animateKeyframesWithDuration
, и все отлично работает.
Ответ 3
Собственно, вы можете использовать те же самые флагов кривой, которые вы используете для animateWithDuration: delay: options: animations: completion:. Просто "двоичный" или "другой" с другими параметрами в вашем вызове animateKeyframesWithDuration: delay: options: animations: completion:
Документация запутанна, но она работает.
Значения кривых, которые вы можете использовать, следующие:
UIViewAnimationOptionCurveEaseInOut = 0 << 16,
UIViewAnimationOptionCurveEaseIn = 1 << 16,
UIViewAnimationOptionCurveEaseOut = 2 << 16,
UIViewAnimationOptionCurveLinear = 3 << 16,
Кривая анимации по умолчанию, которую вы получаете, равна 0, или простота, непринужденность.
Ответ 4
Здесь хорошее и чистое решение Swift, с которым я придумал:
extension UIViewKeyframeAnimationOptions {
init(animationOptions: UIViewAnimationOptions) {
rawValue = animationOptions.rawValue
}
}
Использование:
UIViewKeyframeAnimationOptions(animationOptions: .CurveEaseOut)
Ответ 5
Ответ от @eskimwier не работал у меня при попытке установить кривую на linear
для animateKeyframes(withDuration:delay:options:animations:completion:)
. Это было в Swift 3, Xcode 8.2.1.
Моя анимация по умолчанию не соответствует easeInOut
(медленный запуск, быстрее в середине, медленный в конце). Apple изменила кривую по умолчанию?
Во всяком случае, мне нужна линейная кривая, и попробовал предложенный выше подход использовать UIViewAnimationOptions
с анимацией ключевого кадра:
let animationOptions: UIViewAnimationOptions = .curveLinear
var keyframeAnimationOptions: UIViewKeyframeAnimationOptions = UIViewKeyframeAnimationOptions(rawValue: animationOptions.rawValue)
UIView.animateKeyframes(withDuration: 3, delay: 0, options: [keyframeAnimationOptions], animations: {
//... animations here ...
}, completion: nil)
Это не имело никакого эффекта. Единственное, что сработало для меня, это сделать это, прежде чем вызывать animateKeyframes:
UIView.setAnimationCurve(UIViewAnimationCurve.linear)