摇一摇原理,附动效一枚

本文详细介绍如何在iOS应用中实现摇一摇功能,并通过关键帧动画实现手机模拟摇动效果,包括颜色渐变和手机图片晃动的具体实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

之前一直以为摇一摇实现比较复杂,工作中写过后,发现其实原理很简单,相对麻烦的还是UI。


/**
 *   If a responder object returns YES from this method, it becomes the first responder and can receive touch events and action messages. Subclasses must override this method to be able to become first responder.
 *
 *  @return Returns NO by default
 */
- (BOOL)canBecomeFirstResponder
{
    return YES;
}
- (void)motionBegan:(UIEventSubtype)motion withEvent:(UIEvent *)event
{
    if (motion == UIEventSubtypeMotionShake)
    {
        NSLog(@"motionBegan ~~~");
    }
}
- (void)motionEnded:(UIEventSubtype)motion withEvent:(UIEvent *)event
{
    if(motion != UIEventSubtypeMotionShake) return;
    NSLog(@"motionEnded ~~~");
}
- (void)motionCancelled:(UIEventSubtype)motion withEvent:(UIEvent *)event
{
    NSLog(@"motionCancelled ~~~");
}


第一次上传Gif图,是用一个叫 Gitrocket 的软件生成的。很简单,先用QuickTime Player手机录屏,保存后,将视频直接拖到Gitrocket即可,比较方便。

Gitrocket下载地址:http://www.gifrocket.com/

可以将该动画分为两部分:颜色的渐变和手机图片的左右晃动。

渐变实现:

    [UIView beginAnimations:nil context:nil];
    [UIView    setAnimationCurve: UIViewAnimationCurveLinear];
    [UIView    setAnimationDelegate:self];
    [UIView    setAnimationDuration:0.2];
    circleBgView.backgroundColor = [UIColor colorWithRed:255 / 255.0f green:153 / 255.0f blue:0 / 255.0f alpha:1];//渐变后的颜色
    [UIView commitAnimations];


手机晃动:( CAkeyframeAnimation关键帧动画实现

    CAKeyframeAnimation *keyAnim = [CAKeyframeAnimation animationWithKeyPath:@"transform"];
    CATransform3D rotation0 = CATransform3DMakeRotation(0 * M_PI/180, 0, 0, -1);
    CATransform3D rotation1 = CATransform3DMakeRotation(0 * M_PI/180, 0, 0, -1);
    CATransform3D rotation2 = CATransform3DMakeRotation(-75 * M_PI/180, 0, 0, -1);
    CATransform3D rotation3 = CATransform3DMakeRotation(75 * M_PI/180, 0, 0, -1);
    CATransform3D rotation4 = CATransform3DMakeRotation(-45 * M_PI/180, 0, 0, -1);
    CATransform3D rotation5 = CATransform3DMakeRotation(45 * M_PI/180, 0, 0, -1);
    CATransform3D rotation6 = CATransform3DMakeRotation(-30 * M_PI/180, 0, 0, -1);
    CATransform3D rotation7 = CATransform3DMakeRotation(30 * M_PI/180, 0, 0, -1);
    CATransform3D rotation8 = CATransform3DMakeRotation(-20 * M_PI/180, 0, 0, -1);
    CATransform3D rotation9 = CATransform3DMakeRotation(20 * M_PI/180, 0, 0, -1);
    CATransform3D rotation10 = CATransform3DMakeRotation(-10 * M_PI/180, 0, 0, -1);
    CATransform3D rotation11 = CATransform3DMakeRotation(10 * M_PI/180, 0, 0, -1);
    CATransform3D rotation12 = CATransform3DMakeRotation(0 * M_PI/180, 0, 0, -1);
    CATransform3D rotation13 = CATransform3DMakeRotation(0 * M_PI/180, 0, 0, -1);
    
   
    [keyAnim setValues:[NSArray arrayWithObjects:
                        [NSValue valueWithCATransform3D:rotation0],
                        [NSValue valueWithCATransform3D:rotation1],
                        [NSValue valueWithCATransform3D:rotation2],
                        [NSValue valueWithCATransform3D:rotation3],
                        [NSValue valueWithCATransform3D:rotation4],
                        [NSValue valueWithCATransform3D:rotation5],
                        [NSValue valueWithCATransform3D:rotation6],
                        [NSValue valueWithCATransform3D:rotation7],
                        [NSValue valueWithCATransform3D:rotation8],
                        [NSValue valueWithCATransform3D:rotation9],
                        [NSValue valueWithCATransform3D:rotation10],
                        [NSValue valueWithCATransform3D:rotation11],
                        [NSValue valueWithCATransform3D:rotation12],
                        [NSValue valueWithCATransform3D:rotation13],
                        nil]];
    [keyAnim setKeyTimes:[NSArray arrayWithObjects:
                          [NSNumber numberWithFloat:0.0f],
                          [NSNumber numberWithFloat:0.1039f],
                          [NSNumber numberWithFloat:0.1396f],
                          [NSNumber numberWithFloat:0.2110f],
                          [NSNumber numberWithFloat:0.2824f],
                          [NSNumber numberWithFloat:0.3538f],
                          [NSNumber numberWithFloat:0.4252f],
                          [NSNumber numberWithFloat:0.4966f],
                          [NSNumber numberWithFloat:0.5680f],
                          [NSNumber numberWithFloat:0.6394f],
                          [NSNumber numberWithFloat:0.7108f],
                          [NSNumber numberWithFloat:0.7822f],
                          [NSNumber numberWithFloat:0.8536f],
                          [NSNumber numberWithFloat:1.0f],
                          nil]];
    [keyAnim setDuration:1.925f];
    [keyAnim setFillMode:kCAFillModeForwards];
    [keyAnim setRemovedOnCompletion:NO];
    [shakeImageView.layer addAnimation:keyAnim forKey:nil];


关键帧示意图:



要注意的一点:可能摇过之后,动画还没有结束,但是motionEnded回调已经执行完毕,这时候可以继续摇第二次。所以可根据需求在相应位置加控制变量,保证动画结束之后才可以下次摇一摇的操作。




demo:https://github.com/Lynnll/HaveAShake.git

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值