Mimic UIAlertView Bounce?
Каков наилучший способ подражать подпрыгивающей анимации из UIAlertView на iPhone? Есть ли какой-то встроенный механизм для этого? Сам UIAlertView не будет работать для моих нужд.
Я просмотрел кривые анимации, но из того, что я могу сказать, единственные, которые они предоставляют, - это easeIn, easeOut и linear.
Ответы
Ответ 1
Вы можете использовать 2 анимации, одну для всплытия до очень большой, а другую - для масштабирования до нормального размера.
(Это использование подхода UIAlertView
внутри.)
В качестве альтернативы вы можете использовать нижний уровень CAAnimation
и использовать +[CAMediaTimingFunction functionWithControlPoints::::]
для создания собственной кривой.
Ответ 2
UIAlertView использует более сложную анимацию:
- масштаб до 100%
- масштаб меньше 100%
- масштаб до 100%
Здесь реализация с использованием CAKeyFrameAnimation
:
view.alpha = 0;
[UIView animateWithDuration:0.1 animations:^{view.alpha = 1.0;}];
CAKeyframeAnimation *bounceAnimation = [CAKeyframeAnimation animationWithKeyPath:@"transform.scale"];
bounceAnimation.values = @[@0.01f, @1.1f, @0.8f, @1.0f];
bounceAnimation.keyTimes = @[@0.0f, @0.5f, @0.75f, @1.0f];
bounceAnimation.duration = 0.4;
[view.layer addAnimation:bounceAnimation forKey:@"bounce"];
Ответ 3
Я исследовал, как анимации добавляются к слою UIAlertView
путем swizzling -[CALayer addAnimation:forKey:]
. Вот значения, которые я получил для анимаций масштабирования, которые он выполняет:
0.01f -> 1.10f -> 0.90f -> 1.00f
с длительностью
0.2s, 0.1s, 0.1s
.
Все анимации используют легкость в/отключении функции синхронизации. Вот CAKeyframeAnimation
, который инкапсулирует эту логику:
CAKeyframeAnimation *bounceAnimation = [CAKeyframeAnimation animationWithKeyPath:@"transform"];
bounceAnimation.fillMode = kCAFillModeBoth;
bounceAnimation.removedOnCompletion = YES;
bounceAnimation.duration = 0.4;
bounceAnimation.values = @[
[NSValue valueWithCATransform3D:CATransform3DMakeScale(0.01f, 0.01f, 0.01f)],
[NSValue valueWithCATransform3D:CATransform3DMakeScale(1.1f, 1.1f, 1.1f)],
[NSValue valueWithCATransform3D:CATransform3DMakeScale(0.9f, 0.9f, 0.9f)],
[NSValue valueWithCATransform3D:CATransform3DIdentity]];
bounceAnimation.keyTimes = @[@0.0f, @0.5f, @0.75f, @1.0f];
bounceAnimation.timingFunctions = @[
[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut],
[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut],
[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]];
Я считаю, что UIAlertView
также выполняет простую непрозрачную анимацию от 0.0f
до 1.0f
по общей длительности анимации преобразования (0.4
).
Ответ 4
Вот как я это сделал для приложения, над которым я работаю. Эффект, который я искал, подпрыгивал, когда вы нажимали вид. Экспериментируйте со значениями, соответствующими вашему вкусу и желаемой скорости эффекта.
- (void) bounceView:(UIView*)bouncer
{
// set duration to whatever you want
float duration = 1.25;
// use a consistent frame rate for smooth animation.
// experiment to your taste
float numSteps = 15 * duration;
// scale the image up and down, halving the distance each time
[UIView animateKeyframesWithDuration:duration
delay:0
options:UIViewKeyframeAnimationOptionCalculationModeCubic
animations:^{
float minScale = 0.50f; // minimum amount of shrink
float maxScale = 1.75f; // maximum amount of grow
for(int i = 0; i< numSteps*2; i+=2)
{
// bounce down
[UIView addKeyframeWithRelativeStartTime:duration/numSteps * i
relativeDuration:duration/numSteps
animations:^{
bouncer.layer.transform = CATransform3DMakeScale(minScale, minScale, 1);
}];
// bounce up
[UIView addKeyframeWithRelativeStartTime:duration/numSteps * (i+1)
relativeDuration:duration/numSteps
animations:^{
bouncer.layer.transform = CATransform3DMakeScale(maxScale, maxScale, 1);
}];
// cut min scale halfway to identity
minScale = minScale + (1.0f - minScale) / 2.0f;
// cut max scale halfway to identity
maxScale = 1.0f + (maxScale - 1.0f) / 2.0f;
}
} completion:^(BOOL finished) {
// quickly smooth out any rounding errors
[UIView animateWithDuration:0.5*duration/numSteps animations:^{
bouncer.layer.transform = CATransform3DIdentity;
}];
}];
}