В настоящее время мы разрабатываем приложение, содержащее ряд значков. Мы хотим, чтобы значки покачивались, как анимация удаления приложения, при нажатии. Каким будет лучший способ кодировать эту последовательность анимации?
Как создать анимацию покачивания, подобную анимации удаления 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/...