如何创建iPhone的摇摆图标效果?

jea*_*iey 52 iphone animation rotation ios

我想在我的应用程序中来回摆动图像,类似于当你按下它时iPhone图标的摆动.最好的方法是什么?

这是我第一次涉足不使用动画GIF的动画.我认为这个想法是来回轻微旋转图像以产生摆动效果.我已经看过使用CABasicAnimation和CAKeyframeAnimation.CABasicAnimation每次重复时都会创建一个抖动,因为它会跳转到from位置并且不会向内插回.CAKeyframeAnimation似乎是解决方案,除了我无法让它工作.我肯定错过了什么.这是我使用CAKeyframeAnimation的代码(不起作用):

    NSString *keypath = @"wobbleImage";
CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:keypath];
animation.duration = 1.0f;
animation.delegate = self;
animation.repeatCount = 5;

CGFloat wobbleAngle = 0.0872664626f;
NSValue *initial = [NSValue valueWithCATransform3D:CATransform3DMakeRotation(0.0f, 0.0f, 0.0f, 1.0f)];
NSValue *middle = [NSValue valueWithCATransform3D:CATransform3DMakeRotation(wobbleAngle, 0.0f, 0.0f, 1.0f)];
NSValue *final = [NSValue valueWithCATransform3D:CATransform3DMakeRotation(-wobbleAngle, 0.0f, 0.0f, 1.0f)];
animation.values = [NSArray arrayWithObjects:initial, middle, final, nil];

[imageView.layer addAnimation:animation forKey:keypath];
Run Code Online (Sandbox Code Playgroud)


或者可能有一个我只是缺少的完全简单的解决方案.感谢任何指针.谢谢!

Ram*_*min 92

简单的方法:

#define RADIANS(degrees) (((degrees) * M_PI) / 180.0)

CGAffineTransform leftWobble = CGAffineTransformRotate(CGAffineTransformIdentity, RADIANS(-5.0));
CGAffineTransform rightWobble = CGAffineTransformRotate(CGAffineTransformIdentity, RADIANS(5.0));

itemView.transform = leftWobble;  // starting point

[UIView beginAnimations:@"wobble" context:itemView];
[UIView setAnimationRepeatAutoreverses:YES]; // important
[UIView setAnimationRepeatCount:10];
[UIView setAnimationDuration:0.25];
[UIView setAnimationDelegate:self];
[UIView setAnimationDidStopSelector:@selector(wobbleEnded:finished:context:)];

itemView.transform = rightWobble; // end here & auto-reverse

[UIView commitAnimations];

...

- (void) wobbleEnded:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context 
{
     if ([finished boolValue]) {
        UIView* item = (UIView *)context;
        item.transform = CGAffineTransformIdentity;
     }
}
Run Code Online (Sandbox Code Playgroud)

可能必须玩时间和角度,但这应该让你开始.

编辑:我编辑了响应以添加代码,以便在完成后将项目恢复到原始状态.另请注意,您可以使用beginAnimations上下文值将任何内容传递给start/stop方法.在这种情况下,它是摆动对象本身,因此您不必依赖特定的ivars,并且该方法可用于任何基于UIView的通用对象(即文本标签,图像等)


Pie*_*ter 92

Ramin的答案非常好,但是从OS4开始,使用animateWithDuration也可以在一个简单的函数中实现相同的效果.

(改编他未来googlers的榜样)

#define RADIANS(degrees) (((degrees) * M_PI) / 180.0)

- (void)startWobble {
 itemView.transform = CGAffineTransformRotate(CGAffineTransformIdentity, RADIANS(-5));

 [UIView animateWithDuration:0.25 
      delay:0.0 
      options:(UIViewAnimationOptionAllowUserInteraction | UIViewAnimationOptionRepeat | UIViewAnimationOptionAutoreverse)
      animations:^ {
       itemView.transform = CGAffineTransformRotate(CGAffineTransformIdentity, RADIANS(5));
      }
      completion:NULL
 ];
}

- (void)stopWobble {
 [UIView animateWithDuration:0.25
      delay:0.0 
      options:(UIViewAnimationOptionAllowUserInteraction | UIViewAnimationOptionBeginFromCurrentState | UIViewAnimationOptionCurveLinear)
      animations:^ {
       itemView.transform = CGAffineTransformIdentity;
      }
      completion:NULL
  ];
}
Run Code Online (Sandbox Code Playgroud)

  • 非常好.我发现较小的角度(3或4度)和较短的动画时间(.1秒)更接近主屏幕动画. (3认同)

doc*_*ang 14

您应该使用CAKeyframeAnimation更平滑的动画.

+ (void) animationKeyFramed: (CALayer *) layer 
                   delegate: (id) object
              forKey: (NSString *) key {

    CAKeyframeAnimation *animation;
    animation = [CAKeyframeAnimation animationWithKeyPath:@"transform.rotation.z"];
    animation.duration = 0.4;
    animation.cumulative = YES;
    animation.repeatCount = 2;
    animation.values = [NSArray arrayWithObjects:
            [NSNumber numberWithFloat: 0.0], 
            [NSNumber numberWithFloat: RADIANS(-9.0)], 
            [NSNumber numberWithFloat: 0.0],
            [NSNumber numberWithFloat: RADIANS(9.0)],
            [NSNumber numberWithFloat: 0.0], nil];
    animation.fillMode = kCAFillModeForwards;
    animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];
    animation.removedOnCompletion = NO;
    animation.delegate = object;

    [layer addAnimation:animation forKey:key];
}
Run Code Online (Sandbox Code Playgroud)


Kri*_*son 9

我编写了一个示例应用程序,试图复制主屏幕抖动和图标移动:iPhone示例代码:Tiles

  • 我很欣赏这个代码示例还包括Y方向的翻译; 这是其他人的解决方案所缺少的微妙效果. (3认同)