之前一直以为摇一摇实现比较复杂,工作中写过后,发现其实原理很简单,相对麻烦的还是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 *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回调已经执行完毕,这时候可以继续摇第二次。所以可根据需求在相应位置加控制变量,保证动画结束之后才可以下次摇一摇的操作。