Как создать анимацию покачивания, подобную анимации удаления iphone
В настоящее время мы разрабатываем приложение, содержащее ряд значков. Мы хотим, чтобы значки покачивались, как анимация удаления приложения, при нажатии. Каким будет лучший способ кодировать эту последовательность анимации?
Ответы
Ответ 1
Ответ Винзиуса очень крут. Однако колебание только вращается от 0 радиан до 0,08. Таким образом, колебание может выглядеть немного неуравновешенным. Если вы получите эту же проблему, вы можете добавить как отрицательное, так и положительное вращение, используя CAKeyframeAnimation, а не CABasicRotation:
- (CAAnimation*)getShakeAnimation
{
CAKeyframeAnimation* animation = [CAKeyframeAnimation animationWithKeyPath:@"transform"];
CGFloat wobbleAngle = 0.06f;
NSValue* valLeft = [NSValue valueWithCATransform3D:CATransform3DMakeRotation(wobbleAngle, 0.0f, 0.0f, 1.0f)];
NSValue* valRight = [NSValue valueWithCATransform3D:CATransform3DMakeRotation(-wobbleAngle, 0.0f, 0.0f, 1.0f)];
animation.values = [NSArray arrayWithObjects:valLeft, valRight, nil];
animation.autoreverses = YES;
animation.duration = 0.125;
animation.repeatCount = HUGE_VALF;
return animation;
}
Вы можете использовать этот метод анимации для своего вида или кнопки следующим образом.
[self.yourbutton.layer addAnimation:[self getShakeAnimation] forKey:@""];
Ответ 2
Посмотрев на реализацию iOS немного ближе, есть две вещи, которые делают их более реалистичными, чем упомянутый здесь код:
- Значки, похоже, имеют отскок, а также поворот
- Каждый значок имеет свое собственное время - они не все синхронизированы.
Я основывался на ответах здесь (и с некоторой помощью из этого answer), чтобы добавить поворот, отскок и немного случайности к продолжительности каждого анимации.
#define kWiggleBounceY 4.0f
#define kWiggleBounceDuration 0.12
#define kWiggleBounceDurationVariance 0.025
#define kWiggleRotateAngle 0.06f
#define kWiggleRotateDuration 0.1
#define kWiggleRotateDurationVariance 0.025
-(void)startWiggling {
[UIView animateWithDuration:0
animations:^{
[self.layer addAnimation:[self rotationAnimation] forKey:@"rotation"];
[self.layer addAnimation:[self bounceAnimation] forKey:@"bounce"];
self.transform = CGAffineTransformIdentity;
}];
}
-(CAAnimation*)rotationAnimation {
CAKeyframeAnimation* animation = [CAKeyframeAnimation animationWithKeyPath:@"transform.rotation.z"];
animation.values = @[@(-kWiggleRotateAngle), @(kWiggleRotateAngle)];
animation.autoreverses = YES;
animation.duration = [self randomizeInterval:kWiggleRotateDuration
withVariance:kWiggleRotateDurationVariance];
animation.repeatCount = HUGE_VALF;
return animation;
}
-(CAAnimation*)bounceAnimation {
CAKeyframeAnimation* animation = [CAKeyframeAnimation animationWithKeyPath:@"transform.translation.y"];
animation.values = @[@(kWiggleBounceY), @(0.0)];
animation.autoreverses = YES;
animation.duration = [self randomizeInterval:kWiggleBounceDuration
withVariance:kWiggleBounceDurationVariance];
animation.repeatCount = HUGE_VALF;
return animation;
}
-(NSTimeInterval)randomizeInterval:(NSTimeInterval)interval withVariance:(double)variance {
double random = (arc4random_uniform(1000) - 500.0) / 500.0;
return interval + variance * random;
}
Я реализовал этот код в UICollectionView, у которого было 30 элементов, и производительность была безупречной на iPad 2.
Ответ 3
Я попытался сделать что-то подобное для iPad-приложения.
Я попытался сделать несколько поворотов (с помощью CAAnimation) для представления. Вот пример кода, который я написал:
- (CAAnimation*)getShakeAnimation {
CABasicAnimation *animation;
CATransform3D transform;
// Create the rotation matrix
transform = CATransform3DMakeRotation(0.08, 0, 0, 1.0);
// Create a basic animation to animate the layer transform
animation = [CABasicAnimation animationWithKeyPath:@"transform"];
// Assign the transform as the animation value
animation.toValue = [NSValue valueWithCATransform3D:transform];
animation.autoreverses = YES;
animation.duration = 0.1;
animation.repeatCount = HUGE_VALF;
return animation;
}
И вы должны попытаться применить его к своему слою (с функцией: addAnimation).
Здесь свойство autoreverses состоит в чередовании левой и правой ориентации.
Попробуйте установить другие значения на угол и продолжительность.
Но в моем случае мне пришлось добавить другие углы к методу CATransform3DMakeRotation, в зависимости от начальной ориентации слоя ^^
Удачи!
Винсент
Ответ 4
SWIFT: -
let transformAnim = CAKeyframeAnimation(keyPath:"transform")
transformAnim.values = [NSValue(CATransform3D: CATransform3DMakeRotation(0.04, 0.0, 0.0, 1.0)),NSValue(CATransform3D: CATransform3DMakeRotation(-0.04 , 0, 0, 1))]
transformAnim.autoreverses = true
transformAnim.duration = (Double(indexPath.row)%2) == 0 ? 0.115 : 0.105
transformAnim.repeatCount = Float.infinity
self.layer.addAnimation(transformAnim, forKey: "transform")
![]()
Цель C: -
-(CAKeyframeAnimation *)wiggleView
{
CAKeyframeAnimation* animation = [CAKeyframeAnimation animationWithKeyPath:@"transform"];
CGFloat wobbleAngle = 0.04f;
NSValue* valLeft = [NSValue valueWithCATransform3D:CATransform3DMakeRotation(wobbleAngle, 0.0f, 0.0f, 1.0f)];
NSValue* valRight = [NSValue valueWithCATransform3D:CATransform3DMakeRotation(-wobbleAngle, 0.0f, 0.0f, 1.0f)];
animation.values = [NSArray arrayWithObjects:valLeft, valRight, nil];
animation.autoreverses = YES;
animation.duration = 0.125;
animation.repeatCount = HUGE_VALF;
return animation;
}
Ответ 5
Переписал ответ Себастьяна в Свифт 3.
let wiggleBounceY = 4.0
let wiggleBounceDuration = 0.12
let wiggleBounceDurationVariance = 0.025
let wiggleRotateAngle = 0.06
let wiggleRotateDuration = 0.10
let wiggleRotateDurationVariance = 0.025
func randomize(interval: TimeInterval, withVariance variance: Double) -> Double{
let random = (Double(arc4random_uniform(1000)) - 500.0) / 500.0
return interval + variance * random
}
func startWiggle(for view: UIView){
//Create rotation animation
let rotationAnim = CAKeyframeAnimation(keyPath: "transform.rotation.z")
rotationAnim.values = [-wiggleRotateAngle, wiggleRotateAngle]
rotationAnim.autoreverses = true
rotationAnim.duration = randomize(interval: wiggleRotateDuration, withVariance: wiggleRotateDurationVariance)
rotationAnim.repeatCount = HUGE
//Create bounce animation
let bounceAnimation = CAKeyframeAnimation(keyPath: "transform.translation.y")
bounceAnimation.values = [wiggleBounceY, 0]
bounceAnimation.autoreverses = true
bounceAnimation.duration = randomize(interval: wiggleBounceDuration, withVariance: wiggleBounceDurationVariance)
bounceAnimation.repeatCount = HUGE
//Apply animations to view
UIView.animate(withDuration: 0) {
view.layer.add(rotationAnim, forKey: "rotation")
view.layer.add(bounceAnimation, forKey: "bounce")
view.transform = .identity
}
}
func stopWiggle(for view: UIView){
view.layer.removeAllAnimations()
}
Ответ 6
func startWiggling() {
deleteButton.isHidden = false
guard contentView.layer.animation(forKey: "wiggle") == nil else { return }
guard contentView.layer.animation(forKey: "bounce") == nil else { return }
let angle = 0.04
let wiggle = CAKeyframeAnimation(keyPath: "transform.rotation.z")
wiggle.values = [-angle, angle]
wiggle.autoreverses = true
wiggle.duration = randomInterval(0.1, variance: 0.025)
wiggle.repeatCount = Float.infinity
contentView.layer.add(wiggle, forKey: "wiggle")
let bounce = CAKeyframeAnimation(keyPath: "transform.translation.y")
bounce.values = [4.0, 0.0]
bounce.autoreverses = true
bounce.duration = randomInterval(0.12, variance: 0.025)
bounce.repeatCount = Float.infinity
contentView.layer.add(bounce, forKey: "bounce")
}
func stopWiggling() {
deleteButton.isHidden = true
contentView.layer.removeAllAnimations()
}
Посмотрите на этот iOS SpingBoard пример
Ответ 7
Отредактированный код paiego, который соответствует моим потребностям: обратная связь с анимацией изображения при действии пользователя (коснитесь). Это происходит один раз - это не постоянное вихрь, как приложение SpringBoard для редактирования анимации.
- (CAAnimation *)shakeAnimation {
CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:@"transform"];
CGFloat wobbleAngle = 0.06f;
NSValue *valLeft;
NSValue *valRight;
NSMutableArray *values = [NSMutableArray new];
for (int i = 0; i < 5; i++) {
valLeft = [NSValue valueWithCATransform3D:CATransform3DMakeRotation(wobbleAngle, 0.0f, 0.0f, 1.0f)];
valRight = [NSValue valueWithCATransform3D:CATransform3DMakeRotation(-wobbleAngle, 0.0f, 0.0f, 1.0f)];
[values addObjectsFromArray:@[valLeft, valRight]];
wobbleAngle*=0.66;
}
animation.values = [values copy];
animation.duration = 0.7;
return animation;
}
Использование:
[your_view.layer addAnimation:[self shakeAnimation] forKey:@""]; //do the shake animation
your_view.transform = CGAffineTransformIdentity; //return the view back to original
Надеюсь, это поможет кому-то еще.
Ответ 8
Отвечала в другом потоке версия Swift 4 того, что, по-видимому, принадлежит собственному алгоритму Apple:
fooobar.com/info/173143/...